From cec03fd5ca40fa95cd1c67d66b6e2aaf90de395c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 15:22:01 +0000 Subject: [PATCH 001/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6757 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MAKE/Makefile.serial | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial index f2cae6dcc8..30196c40aa 100755 --- a/src/MAKE/Makefile.serial +++ b/src/MAKE/Makefile.serial @@ -45,7 +45,7 @@ MPI_LIB = ../STUBS/libmpi.a # PATH = path for FFT library # LIB = name of FFT library -FFT_INC = -DFFT_NONE +FFT_INC = FFT_PATH = FFT_LIB = From d2518f343ecf84417fdf2479c7061b46365ccee7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 15:22:08 +0000 Subject: [PATCH 002/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6758 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/lammps.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lammps.cpp b/src/lammps.cpp index 6f560b2d49..e5342c1e31 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -14,8 +14,20 @@ #include "mpi.h" #include "string.h" #include "lammps.h" -#include "memory.h" -#include "error.h" +#include "style_angle.h" +#include "style_atom.h" +#include "style_bond.h" +#include "style_command.h" +#include "style_compute.h" +#include "style_dihedral.h" +#include "style_dump.h" +#include "style_fix.h" +#include "style_improper.h" +#include "style_integrate.h" +#include "style_kspace.h" +#include "style_minimize.h" +#include "style_pair.h" +#include "style_region.h" #include "universe.h" #include "input.h" #include "atom.h" @@ -29,6 +41,8 @@ #include "output.h" #include "accelerator_cuda.h" #include "timer.h" +#include "memory.h" +#include "error.h" using namespace LAMMPS_NS; From 1490fa26067fcab969ae39469ed0ef6d6dd14f23 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 15:25:59 +0000 Subject: [PATCH 003/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6759 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/comm.cpp | 4 ++-- src/input.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/comm.cpp b/src/comm.cpp index 2d64ec3bf5..b5008dc3af 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -37,7 +37,7 @@ #include "error.h" #include "memory.h" -#ifdef LMP_OPENMP +#ifdef _OPENMP #include "omp.h" #endif @@ -77,7 +77,7 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp) // need to be in a parallel area for this operation nthreads = 1; -#ifdef LMP_OPENMP +#ifdef _OPENMP #pragma omp parallel default(shared) { #pragma omp master diff --git a/src/input.cpp b/src/input.cpp index fa10ea0064..05cb1f4412 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -46,7 +46,7 @@ #include "error.h" #include "memory.h" -#ifdef LMP_OPENMP +#ifdef _OPENMP #include "omp.h" #endif @@ -1141,12 +1141,12 @@ void Input::package() } else if (strcmp(arg[0],"omp") == 0) { -#ifdef LMP_OPENMP +#ifdef _OPENMP if (narg != 2) error->all("Illegal package command"); comm->nthreads = atoi(arg[1]); if (comm->nthreads < 1) error->all("Illegal package command"); - omp_set_num_threads(nthr); + omp_set_num_threads(comm->nthreads); if (me == 0) { if (screen) fprintf(screen," reset %d OpenMP thread(s) per MPI task\n", From 301dad125fa7d419bcfd08266b2cc9116e1abfa9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 17:07:41 +0000 Subject: [PATCH 004/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6760 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/OPT/pair_eam_alloy_opt.cpp | 10 + src/OPT/pair_eam_alloy_opt.h | 4 - src/OPT/pair_eam_fs_opt.cpp | 10 + src/OPT/pair_eam_fs_opt.h | 5 - src/OPT/pair_eam_opt.cpp | 302 ++++++++++++++++++++++ src/OPT/pair_eam_opt.h | 308 ---------------------- src/OPT/pair_lj_charmm_coul_long_opt.cpp | 294 +++++++++++++++++++++ src/OPT/pair_lj_charmm_coul_long_opt.h | 309 ----------------------- src/OPT/pair_lj_cut_opt.cpp | 153 +++++++++++ src/OPT/pair_lj_cut_opt.h | 158 ------------ src/OPT/pair_morse_opt.cpp | 150 +++++++++++ src/OPT/pair_morse_opt.h | 155 ------------ 12 files changed, 919 insertions(+), 939 deletions(-) diff --git a/src/OPT/pair_eam_alloy_opt.cpp b/src/OPT/pair_eam_alloy_opt.cpp index 8bf4acfe04..0deaf8b430 100644 --- a/src/OPT/pair_eam_alloy_opt.cpp +++ b/src/OPT/pair_eam_alloy_opt.cpp @@ -11,6 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing authors: + James Fischer, High Performance Technologies, Inc. + Charles Cornwell, High Performance Technologies, Inc. + David Richie, Stone Ridge Technology + Vincent Natoli, Stone Ridge Technology +------------------------------------------------------------------------- */ + #include "pair_eam_alloy_opt.h" using namespace LAMMPS_NS; @@ -18,6 +26,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- multiple inheritance from two parent classes invoke constructor of grandparent class, then of each parent + inherit optimized compute() from PairEAMOpt + inherit everything else from PairEAMAlloy ------------------------------------------------------------------------- */ PairEAMAlloyOpt::PairEAMAlloyOpt(LAMMPS *lmp) : diff --git a/src/OPT/pair_eam_alloy_opt.h b/src/OPT/pair_eam_alloy_opt.h index 507fa44376..5435f00fa4 100644 --- a/src/OPT/pair_eam_alloy_opt.h +++ b/src/OPT/pair_eam_alloy_opt.h @@ -25,10 +25,6 @@ PairStyle(eam/alloy/opt,PairEAMAlloyOpt) namespace LAMMPS_NS { -// multiple inheritance from two parent classes -// optimized compute() from PairEAMOpt -// everything else from PairEAMAlloy - class PairEAMAlloyOpt : public PairEAMAlloy, public PairEAMOpt { public: PairEAMAlloyOpt(class LAMMPS *); diff --git a/src/OPT/pair_eam_fs_opt.cpp b/src/OPT/pair_eam_fs_opt.cpp index 11e8b222d6..a097eec2b6 100644 --- a/src/OPT/pair_eam_fs_opt.cpp +++ b/src/OPT/pair_eam_fs_opt.cpp @@ -11,6 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing authors: + James Fischer, High Performance Technologies, Inc. + Charles Cornwell, High Performance Technologies, Inc. + David Richie, Stone Ridge Technology + Vincent Natoli, Stone Ridge Technology +------------------------------------------------------------------------- */ + #include "pair_eam_fs_opt.h" using namespace LAMMPS_NS; @@ -18,6 +26,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- multiple inheritance from two parent classes invoke constructor of grandparent class, then of each parent + inherit optimized compute() from PairEAMOpt + inherit everything else from PairEAMFS ------------------------------------------------------------------------- */ PairEAMFSOpt::PairEAMFSOpt(LAMMPS *lmp) : diff --git a/src/OPT/pair_eam_fs_opt.h b/src/OPT/pair_eam_fs_opt.h index 519630880a..b5bfdad4bf 100644 --- a/src/OPT/pair_eam_fs_opt.h +++ b/src/OPT/pair_eam_fs_opt.h @@ -25,10 +25,6 @@ PairStyle(eam/fs/opt,PairEAMFSOpt) namespace LAMMPS_NS { -// multiple inheritance from two parent classes -// optimized compute() from PairEAMOpt -// everything else from PairEAMFS - class PairEAMFSOpt : public PairEAMFS, public PairEAMOpt { public: PairEAMFSOpt(class LAMMPS *); @@ -37,5 +33,4 @@ class PairEAMFSOpt : public PairEAMFS, public PairEAMOpt { } #endif - #endif diff --git a/src/OPT/pair_eam_opt.cpp b/src/OPT/pair_eam_opt.cpp index 43c2d3733e..83a9580b92 100644 --- a/src/OPT/pair_eam_opt.cpp +++ b/src/OPT/pair_eam_opt.cpp @@ -19,10 +19,20 @@ Vincent Natoli, Stone Ridge Technology ------------------------------------------------------------------------- */ +#include "math.h" +#include "stdlib.h" #include "pair_eam_opt.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neigh_list.h" +#include "memory.h" using namespace LAMMPS_NS; +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + /* ---------------------------------------------------------------------- */ PairEAMOpt::PairEAMOpt(LAMMPS *lmp) : PairEAM(lmp) {} @@ -47,3 +57,295 @@ void PairEAMOpt::compute(int eflag, int vflag) else return eval<0,0,0>(); } } + +/* ---------------------------------------------------------------------- */ + +template < int EVFLAG, int EFLAG, int NEWTON_PAIR > +void PairEAMOpt::eval() +{ + typedef struct { double x,y,z; } vec3_t; + + typedef struct { + double rhor0i,rhor1i,rhor2i,rhor3i; + double rhor0j,rhor1j,rhor2j,rhor3j; + } fast_alpha_t; + + typedef struct { + double frho0,frho1,frho2,frho3,frho4,frho5,frho6; + double _pad[1]; + } fast_beta_t; + + typedef struct { + double rhor4i,rhor5i,rhor6i; + double rhor4j,rhor5j,rhor6j; + double z2r0,z2r1,z2r2,z2r3,z2r4,z2r5,z2r6; + double _pad[3]; + } fast_gamma_t; + + int i,j,ii,jj,inum,jnum,itype,jtype; + double evdwl = 0.0; + double* __restrict__ coeff; + + // grow energy array if necessary + + if (atom->nmax > nmax) { + memory->sfree(rho); + memory->sfree(fp); + nmax = atom->nmax; + rho = (double *) memory->smalloc(nmax*sizeof(double),"pair:rho"); + fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp"); + } + + double** __restrict__ x = atom->x; + double** __restrict__ f = atom->f; + int* __restrict__ type = atom->type; + int nlocal = atom->nlocal; + + vec3_t* __restrict__ xx = (vec3_t*)x[0]; + vec3_t* __restrict__ ff = (vec3_t*)f[0]; + + double tmp_cutforcesq = cutforcesq; + double tmp_rdr = rdr; + int nr2 = nr-2; + int nr1 = nr-1; + + inum = list->inum; + int* __restrict__ ilist = list->ilist; + int** __restrict__ firstneigh = list->firstneigh; + int* __restrict__ numneigh = list->numneigh; + + int ntypes = atom->ntypes; + int ntypes2 = ntypes*ntypes; + + fast_alpha_t* __restrict__ fast_alpha = + (fast_alpha_t*) malloc(ntypes2*(nr+1)*sizeof(fast_alpha_t)); + for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { + fast_alpha_t* __restrict__ tab = &fast_alpha[i*ntypes*nr+j*nr]; + if (type2rhor[i+1][j+1] >= 0) { + for(int m = 1; m <= nr; m++) { + tab[m].rhor0i = rhor_spline[type2rhor[i+1][j+1]][m][6]; + tab[m].rhor1i = rhor_spline[type2rhor[i+1][j+1]][m][5]; + tab[m].rhor2i = rhor_spline[type2rhor[i+1][j+1]][m][4]; + tab[m].rhor3i = rhor_spline[type2rhor[i+1][j+1]][m][3]; + } + } + if (type2rhor[j+1][i+1] >= 0) { + for(int m = 1; m <= nr; m++) { + tab[m].rhor0j = rhor_spline[type2rhor[j+1][i+1]][m][6]; + tab[m].rhor1j = rhor_spline[type2rhor[j+1][i+1]][m][5]; + tab[m].rhor2j = rhor_spline[type2rhor[j+1][i+1]][m][4]; + tab[m].rhor3j = rhor_spline[type2rhor[j+1][i+1]][m][3]; + } + } + } + fast_alpha_t* __restrict__ tabeight = fast_alpha; + + fast_gamma_t* __restrict__ fast_gamma = + (fast_gamma_t*) malloc(ntypes2*(nr+1)*sizeof(fast_gamma_t)); + for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { + fast_gamma_t* __restrict__ tab = &fast_gamma[i*ntypes*nr+j*nr]; + if (type2rhor[i+1][j+1] >= 0) { + for(int m = 1; m <= nr; m++) { + tab[m].rhor4i = rhor_spline[type2rhor[i+1][j+1]][m][2]; + tab[m].rhor5i = rhor_spline[type2rhor[i+1][j+1]][m][1]; + tab[m].rhor6i = rhor_spline[type2rhor[i+1][j+1]][m][0]; + } + } + if (type2rhor[j+1][i+1] >= 0) { + for(int m = 1; m <= nr; m++) { + tab[m].rhor4j = rhor_spline[type2rhor[j+1][i+1]][m][2]; + tab[m].rhor5j = rhor_spline[type2rhor[j+1][i+1]][m][1]; + tab[m].rhor6j = rhor_spline[type2rhor[j+1][i+1]][m][0]; + tab[m].z2r6 = z2r_spline[type2z2r[i+1][j+1]][m][0]; + } + } + if (type2z2r[i+1][j+1] >= 0) { + for(int m = 1; m <= nr; m++) { + tab[m].z2r0 = z2r_spline[type2z2r[i+1][j+1]][m][6]; + tab[m].z2r1 = z2r_spline[type2z2r[i+1][j+1]][m][5]; + tab[m].z2r2 = z2r_spline[type2z2r[i+1][j+1]][m][4]; + tab[m].z2r3 = z2r_spline[type2z2r[i+1][j+1]][m][3]; + tab[m].z2r4 = z2r_spline[type2z2r[i+1][j+1]][m][2]; + tab[m].z2r5 = z2r_spline[type2z2r[i+1][j+1]][m][1]; + tab[m].z2r6 = z2r_spline[type2z2r[i+1][j+1]][m][0]; + } + } + } + fast_gamma_t* __restrict__ tabss = fast_gamma; + + // zero out density + + if (NEWTON_PAIR) { + int m = nlocal + atom->nghost; + for (i = 0; i < m; i++) rho[i] = 0.0; + } else for (i = 0; i < nlocal; i++) rho[i] = 0.0; + + // rho = density at each atom + // loop over neighbors of my atoms + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double xtmp = xx[i].x; + double ytmp = xx[i].y; + double ztmp = xx[i].z; + itype = type[i] - 1; + int* __restrict__ jlist = firstneigh[i]; + jnum = numneigh[i]; + + double tmprho = rho[i]; + fast_alpha_t* __restrict__ tabeighti = &tabeight[itype*ntypes*nr]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < tmp_cutforcesq) { + jtype = type[j] - 1; + + double p = sqrt(rsq)*tmp_rdr; + if ( (int)p <= nr2 ) { + int m = (int)p + 1; + p -= (double)((int)p); + fast_alpha_t& a = tabeighti[jtype*nr+m]; + tmprho += ((a.rhor3j*p+a.rhor2j)*p+a.rhor1j)*p+a.rhor0j; + if (NEWTON_PAIR || j < nlocal) { + rho[j] += ((a.rhor3i*p+a.rhor2i)*p+a.rhor1i)*p+a.rhor0i; + } + } else { + fast_alpha_t& a = tabeighti[jtype*nr+nr1]; + tmprho += a.rhor3j+a.rhor2j+a.rhor1j+a.rhor0j; + if (NEWTON_PAIR || j < nlocal) { + rho[j] += a.rhor3i+a.rhor2i+a.rhor1i+a.rhor0i; + } + } + } + } + rho[i] = tmprho; + } + + // communicate and sum densities + + if (NEWTON_PAIR) comm->reverse_comm_pair(this); + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double p = rho[i]*rdrho; + int m = MIN((int)p,nrho-2); + p -= (double)m; + ++m; + coeff = frho_spline[type2frho[type[i]]][m]; + fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; + if (EFLAG) { + double phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + if (eflag_global) eng_vdwl += phi; + if (eflag_atom) eatom[i] += phi; + } + } + + // communicate derivative of embedding function + + comm->forward_comm_pair(this); + + // compute forces on each atom + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double xtmp = xx[i].x; + double ytmp = xx[i].y; + double ztmp = xx[i].z; + int itype1 = type[i] - 1; + int* __restrict__ jlist = firstneigh[i]; + jnum = numneigh[i]; + + double tmpfx = 0.0; + double tmpfy = 0.0; + double tmpfz = 0.0; + + fast_gamma_t* __restrict__ tabssi = &tabss[itype1*ntypes*nr]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < tmp_cutforcesq) { + jtype = type[j] - 1; + double r = sqrt(rsq); + double rhoip,rhojp,z2,z2p; + double p = r*tmp_rdr; + if ( (int)p <= nr2 ) { + int m = (int) p + 1; + p -= (double)((int) p); + + fast_gamma_t& a = tabssi[jtype*nr+m]; + rhoip = (a.rhor6i*p + a.rhor5i)*p + a.rhor4i; + rhojp = (a.rhor6j*p + a.rhor5j)*p + a.rhor4j; + z2 = ((a.z2r3*p + a.z2r2)*p + a.z2r1)*p + a.z2r0; + z2p = (a.z2r6*p + a.z2r5)*p + a.z2r4; + + } else { + + fast_gamma_t& a = tabssi[jtype*nr+nr1]; + rhoip = a.rhor6i + a.rhor5i + a.rhor4i; + rhojp = a.rhor6j + a.rhor5j + a.rhor4j; + z2 = a.z2r3 + a.z2r2 + a.z2r1 + a.z2r0; + z2p = a.z2r6 + a.z2r5 + a.z2r4; + } + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + double recip = 1.0/r; + double phi = z2*recip; + double phip = z2p*recip - phi*recip; + double psip = fp[i]*rhojp + fp[j]*rhoip + phip; + double fpair = -psip*recip; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) evdwl = phi; + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz); + } + } + + ff[i].x += tmpfx; + ff[i].y += tmpfy; + ff[i].z += tmpfz; + } + + free(fast_alpha); fast_alpha = 0; + free(fast_gamma); fast_gamma = 0; + + if (vflag_fdotr) virial_fdotr_compute(); +} diff --git a/src/OPT/pair_eam_opt.h b/src/OPT/pair_eam_opt.h index c2d302e882..afc7764da9 100644 --- a/src/OPT/pair_eam_opt.h +++ b/src/OPT/pair_eam_opt.h @@ -11,14 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: - James Fischer, High Performance Technologies, Inc. - Charles Cornwell, High Performance Technologies, Inc. - David Richie, Stone Ridge Technology - Vincent Natol, Stone Ridge Technology -------------------------------------------------------------------------- */ - #ifdef PAIR_CLASS PairStyle(eam/opt,PairEAMOpt) @@ -28,17 +20,7 @@ PairStyle(eam/opt,PairEAMOpt) #ifndef LMP_PAIR_EAM_OPT_H #define LMP_PAIR_EAM_OPT_H -#include "math.h" -#include "stdlib.h" #include "pair_eam.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "neigh_list.h" -#include "memory.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) namespace LAMMPS_NS { @@ -54,296 +36,6 @@ class PairEAMOpt : virtual public PairEAM { template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval(); }; -template < int EVFLAG, int EFLAG, int NEWTON_PAIR > -void PairEAMOpt::eval() -{ - typedef struct { double x,y,z; } vec3_t; - - typedef struct { - double rhor0i,rhor1i,rhor2i,rhor3i; - double rhor0j,rhor1j,rhor2j,rhor3j; - } fast_alpha_t; - - typedef struct { - double frho0,frho1,frho2,frho3,frho4,frho5,frho6; - double _pad[1]; - } fast_beta_t; - - typedef struct { - double rhor4i,rhor5i,rhor6i; - double rhor4j,rhor5j,rhor6j; - double z2r0,z2r1,z2r2,z2r3,z2r4,z2r5,z2r6; - double _pad[3]; - } fast_gamma_t; - - int i,j,ii,jj,inum,jnum,itype,jtype; - double evdwl = 0.0; - double* __restrict__ coeff; - - // grow energy array if necessary - - if (atom->nmax > nmax) { - memory->sfree(rho); - memory->sfree(fp); - nmax = atom->nmax; - rho = (double *) memory->smalloc(nmax*sizeof(double),"pair:rho"); - fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp"); - } - - double** __restrict__ x = atom->x; - double** __restrict__ f = atom->f; - int* __restrict__ type = atom->type; - int nlocal = atom->nlocal; - - vec3_t* __restrict__ xx = (vec3_t*)x[0]; - vec3_t* __restrict__ ff = (vec3_t*)f[0]; - - double tmp_cutforcesq = cutforcesq; - double tmp_rdr = rdr; - int nr2 = nr-2; - int nr1 = nr-1; - - inum = list->inum; - int* __restrict__ ilist = list->ilist; - int** __restrict__ firstneigh = list->firstneigh; - int* __restrict__ numneigh = list->numneigh; - - int ntypes = atom->ntypes; - int ntypes2 = ntypes*ntypes; - - fast_alpha_t* __restrict__ fast_alpha = - (fast_alpha_t*) malloc(ntypes2*(nr+1)*sizeof(fast_alpha_t)); - for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { - fast_alpha_t* __restrict__ tab = &fast_alpha[i*ntypes*nr+j*nr]; - if (type2rhor[i+1][j+1] >= 0) { - for(int m = 1; m <= nr; m++) { - tab[m].rhor0i = rhor_spline[type2rhor[i+1][j+1]][m][6]; - tab[m].rhor1i = rhor_spline[type2rhor[i+1][j+1]][m][5]; - tab[m].rhor2i = rhor_spline[type2rhor[i+1][j+1]][m][4]; - tab[m].rhor3i = rhor_spline[type2rhor[i+1][j+1]][m][3]; - } - } - if (type2rhor[j+1][i+1] >= 0) { - for(int m = 1; m <= nr; m++) { - tab[m].rhor0j = rhor_spline[type2rhor[j+1][i+1]][m][6]; - tab[m].rhor1j = rhor_spline[type2rhor[j+1][i+1]][m][5]; - tab[m].rhor2j = rhor_spline[type2rhor[j+1][i+1]][m][4]; - tab[m].rhor3j = rhor_spline[type2rhor[j+1][i+1]][m][3]; - } - } - } - fast_alpha_t* __restrict__ tabeight = fast_alpha; - - fast_gamma_t* __restrict__ fast_gamma = - (fast_gamma_t*) malloc(ntypes2*(nr+1)*sizeof(fast_gamma_t)); - for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { - fast_gamma_t* __restrict__ tab = &fast_gamma[i*ntypes*nr+j*nr]; - if (type2rhor[i+1][j+1] >= 0) { - for(int m = 1; m <= nr; m++) { - tab[m].rhor4i = rhor_spline[type2rhor[i+1][j+1]][m][2]; - tab[m].rhor5i = rhor_spline[type2rhor[i+1][j+1]][m][1]; - tab[m].rhor6i = rhor_spline[type2rhor[i+1][j+1]][m][0]; - } - } - if (type2rhor[j+1][i+1] >= 0) { - for(int m = 1; m <= nr; m++) { - tab[m].rhor4j = rhor_spline[type2rhor[j+1][i+1]][m][2]; - tab[m].rhor5j = rhor_spline[type2rhor[j+1][i+1]][m][1]; - tab[m].rhor6j = rhor_spline[type2rhor[j+1][i+1]][m][0]; - tab[m].z2r6 = z2r_spline[type2z2r[i+1][j+1]][m][0]; - } - } - if (type2z2r[i+1][j+1] >= 0) { - for(int m = 1; m <= nr; m++) { - tab[m].z2r0 = z2r_spline[type2z2r[i+1][j+1]][m][6]; - tab[m].z2r1 = z2r_spline[type2z2r[i+1][j+1]][m][5]; - tab[m].z2r2 = z2r_spline[type2z2r[i+1][j+1]][m][4]; - tab[m].z2r3 = z2r_spline[type2z2r[i+1][j+1]][m][3]; - tab[m].z2r4 = z2r_spline[type2z2r[i+1][j+1]][m][2]; - tab[m].z2r5 = z2r_spline[type2z2r[i+1][j+1]][m][1]; - tab[m].z2r6 = z2r_spline[type2z2r[i+1][j+1]][m][0]; - } - } - } - fast_gamma_t* __restrict__ tabss = fast_gamma; - - // zero out density - - if (NEWTON_PAIR) { - int m = nlocal + atom->nghost; - for (i = 0; i < m; i++) rho[i] = 0.0; - } else for (i = 0; i < nlocal; i++) rho[i] = 0.0; - - // rho = density at each atom - // loop over neighbors of my atoms - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double xtmp = xx[i].x; - double ytmp = xx[i].y; - double ztmp = xx[i].z; - itype = type[i] - 1; - int* __restrict__ jlist = firstneigh[i]; - jnum = numneigh[i]; - - double tmprho = rho[i]; - fast_alpha_t* __restrict__ tabeighti = &tabeight[itype*ntypes*nr]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < tmp_cutforcesq) { - jtype = type[j] - 1; - - double p = sqrt(rsq)*tmp_rdr; - if ( (int)p <= nr2 ) { - int m = (int)p + 1; - p -= (double)((int)p); - fast_alpha_t& a = tabeighti[jtype*nr+m]; - tmprho += ((a.rhor3j*p+a.rhor2j)*p+a.rhor1j)*p+a.rhor0j; - if (NEWTON_PAIR || j < nlocal) { - rho[j] += ((a.rhor3i*p+a.rhor2i)*p+a.rhor1i)*p+a.rhor0i; - } - } else { - fast_alpha_t& a = tabeighti[jtype*nr+nr1]; - tmprho += a.rhor3j+a.rhor2j+a.rhor1j+a.rhor0j; - if (NEWTON_PAIR || j < nlocal) { - rho[j] += a.rhor3i+a.rhor2i+a.rhor1i+a.rhor0i; - } - } - } - } - rho[i] = tmprho; - } - - // communicate and sum densities - - if (NEWTON_PAIR) comm->reverse_comm_pair(this); - - // fp = derivative of embedding energy at each atom - // phi = embedding energy at each atom - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double p = rho[i]*rdrho; - int m = MIN((int)p,nrho-2); - p -= (double)m; - ++m; - coeff = frho_spline[type2frho[type[i]]][m]; - fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; - if (EFLAG) { - double phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; - if (eflag_global) eng_vdwl += phi; - if (eflag_atom) eatom[i] += phi; - } - } - - // communicate derivative of embedding function - - comm->forward_comm_pair(this); - - // compute forces on each atom - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double xtmp = xx[i].x; - double ytmp = xx[i].y; - double ztmp = xx[i].z; - int itype1 = type[i] - 1; - int* __restrict__ jlist = firstneigh[i]; - jnum = numneigh[i]; - - double tmpfx = 0.0; - double tmpfy = 0.0; - double tmpfz = 0.0; - - fast_gamma_t* __restrict__ tabssi = &tabss[itype1*ntypes*nr]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < tmp_cutforcesq) { - jtype = type[j] - 1; - double r = sqrt(rsq); - double rhoip,rhojp,z2,z2p; - double p = r*tmp_rdr; - if ( (int)p <= nr2 ) { - int m = (int) p + 1; - p -= (double)((int) p); - - fast_gamma_t& a = tabssi[jtype*nr+m]; - rhoip = (a.rhor6i*p + a.rhor5i)*p + a.rhor4i; - rhojp = (a.rhor6j*p + a.rhor5j)*p + a.rhor4j; - z2 = ((a.z2r3*p + a.z2r2)*p + a.z2r1)*p + a.z2r0; - z2p = (a.z2r6*p + a.z2r5)*p + a.z2r4; - - } else { - - fast_gamma_t& a = tabssi[jtype*nr+nr1]; - rhoip = a.rhor6i + a.rhor5i + a.rhor4i; - rhojp = a.rhor6j + a.rhor5j + a.rhor4j; - z2 = a.z2r3 + a.z2r2 + a.z2r1 + a.z2r0; - z2p = a.z2r6 + a.z2r5 + a.z2r4; - } - - // rhoip = derivative of (density at atom j due to atom i) - // rhojp = derivative of (density at atom i due to atom j) - // phi = pair potential energy - // phip = phi' - // z2 = phi * r - // z2p = (phi * r)' = (phi' r) + phi - // psip needs both fp[i] and fp[j] terms since r_ij appears in two - // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) - // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip - - double recip = 1.0/r; - double phi = z2*recip; - double phip = z2p*recip - phi*recip; - double psip = fp[i]*rhojp + fp[j]*rhoip + phip; - double fpair = -psip*recip; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) evdwl = phi; - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,0.0,fpair,delx,dely,delz); - } - } - - ff[i].x += tmpfx; - ff[i].y += tmpfy; - ff[i].z += tmpfz; - } - - free(fast_alpha); fast_alpha = 0; - free(fast_gamma); fast_gamma = 0; - - if (vflag_fdotr) virial_fdotr_compute(); -} - } #endif diff --git a/src/OPT/pair_lj_charmm_coul_long_opt.cpp b/src/OPT/pair_lj_charmm_coul_long_opt.cpp index 173c201d12..6049eb2a31 100644 --- a/src/OPT/pair_lj_charmm_coul_long_opt.cpp +++ b/src/OPT/pair_lj_charmm_coul_long_opt.cpp @@ -18,10 +18,26 @@ Vincent Natoli, Stone Ridge Technology ------------------------------------------------------------------------- */ +#include "math.h" +#include "stdlib.h" #include "pair_lj_charmm_coul_long_opt.h" +#include "atom.h" +#include "force.h" +#include "neigh_list.h" using namespace LAMMPS_NS; +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define EWALD_A1 0.254829592 +#define EWALD_A2 -0.284496736 +#define EWALD_A3 1.421413741 +#define EWALD_A4 -1.453152027 +#define EWALD_A5 1.061405429 + /* ---------------------------------------------------------------------- */ PairLJCharmmCoulLongOpt::PairLJCharmmCoulLongOpt(LAMMPS *lmp) : @@ -47,3 +63,281 @@ void PairLJCharmmCoulLongOpt::compute(int eflag, int vflag) else return eval<0,0,0>(); } } + +/* ---------------------------------------------------------------------- */ + +template < int EVFLAG, int EFLAG, int NEWTON_PAIR > +void PairLJCharmmCoulLongOpt::eval() +{ + typedef struct { double x,y,z; } vec3_t; + + typedef struct { + double cutsq,lj1,lj2,lj3,lj4,offset; + double _pad[2]; + } fast_alpha_t; + + int i,j,ii,jj,inum,jnum,itype,jtype,itable,sbindex; + double fraction,table; + double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + double philj,switch1,switch2; + + double rsq; + + double evdwl = 0.0; + double ecoul = 0.0; + + double** __restrict__ x = atom->x; + double** __restrict__ f = atom->f; + double* __restrict__ q = atom->q; + int* __restrict__ type = atom->type; + int nlocal = atom->nlocal; + double* __restrict__ special_coul = force->special_coul; + double* __restrict__ special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + + inum = list->inum; + int* __restrict__ ilist = list->ilist; + int** __restrict__ firstneigh = list->firstneigh; + int* __restrict__ numneigh = list->numneigh; + + vec3_t* __restrict__ xx = (vec3_t*)x[0]; + vec3_t* __restrict__ ff = (vec3_t*)f[0]; + + int ntypes = atom->ntypes; + int ntypes2 = ntypes*ntypes; + + double tmp_coef1 = 1.0/denom_lj; + double tmp_coef2 = cut_ljsq - 3.0*cut_lj_innersq; + + fast_alpha_t* __restrict__ fast_alpha = + (fast_alpha_t*)malloc(ntypes2*sizeof(fast_alpha_t)); + for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { + fast_alpha_t& a = fast_alpha[i*ntypes+j]; + a.cutsq = cutsq[i+1][j+1]; + a.lj1 = lj1[i+1][j+1]; + a.lj2 = lj2[i+1][j+1]; + a.lj3 = lj3[i+1][j+1]; + a.lj4 = lj4[i+1][j+1]; + } + fast_alpha_t* __restrict__ tabsix = fast_alpha; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double qtmp = q[i]; + double xtmp = xx[i].x; + double ytmp = xx[i].y; + double ztmp = xx[i].z; + itype = type[i] - 1; + int* __restrict__ jlist = firstneigh[i]; + jnum = numneigh[i]; + + double tmpfx = 0.0; + double tmpfy = 0.0; + double tmpfz = 0.0; + + fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*) &tabsix[itype*ntypes]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + sbindex = sbmask(j); + + if (sbindex == 0) { + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + rsq = delx*delx + dely*dely + delz*delz; + double tmp_coef3 = qtmp*q[j]; + + if (rsq < cut_bothsq) { + r2inv = 1.0/rsq; + + forcecoul = 0.0; + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * + (EWALD_A1+t*(EWALD_A2+t*(EWALD_A3+t*(EWALD_A4+t*EWALD_A5)))) * + expm2; + prefactor = qqrd2e * tmp_coef3/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = tmp_coef3 * table; + } + } + + forcelj = 0.0; + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j] - 1; + fast_alpha_t& a = tabsixi[jtype]; + forcelj = r6inv * (a.lj1*r6inv - a.lj2); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (tmp_coef2 + 2.0*rsq) * tmp_coef1; + switch2 = 12.0*rsq * (cut_ljsq-rsq) * + (rsq-cut_lj_innersq) * tmp_coef1; + philj = r6inv * (a.lj3*r6inv - a.lj4); + forcelj = forcelj*switch1 + philj*switch2; + } + } + + double fpair = (forcecoul + forcelj) * r2inv; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = tmp_coef3 * table; + } + } else ecoul = 0.0; + + if (rsq < cut_ljsq) { + fast_alpha_t& a = tabsixi[jtype]; + evdwl = r6inv*(a.lj3*r6inv-a.lj4); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (tmp_coef2 + 2.0*rsq) * tmp_coef1; + evdwl *= switch1; + } + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz); + } + + } else { + factor_lj = special_lj[sbindex]; + factor_coul = special_coul[sbindex]; + j &= NEIGHMASK; + + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + rsq = delx*delx + dely*dely + delz*delz; + double tmp_coef3 = qtmp*q[j]; + + if (rsq < cut_bothsq) { + r2inv = 1.0/rsq; + + forcecoul = 0.0; + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * + (EWALD_A1+t*(EWALD_A2+t*(EWALD_A3+t*(EWALD_A4+t*EWALD_A5)))) * + expm2; + prefactor = qqrd2e * tmp_coef3/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) { + forcecoul -= (1.0-factor_coul)*prefactor; + } + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = tmp_coef3 * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = tmp_coef3 * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + } + + forcelj = 0.0; + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j] - 1; + fast_alpha_t& a = tabsixi[jtype]; + forcelj = r6inv * (a.lj1*r6inv - a.lj2); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (tmp_coef2 + 2.0*rsq) * tmp_coef1; + switch2 = 12.0*rsq * (cut_ljsq-rsq) * + (rsq-cut_lj_innersq) * tmp_coef1; + fast_alpha_t& a = tabsixi[jtype]; + philj = r6inv * (a.lj3*r6inv - a.lj4); + forcelj = forcelj*switch1 + philj*switch2; + } + } + + double fpair = (forcecoul + factor_lj*forcelj) * r2inv; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = tmp_coef3 * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + + if (rsq < cut_ljsq) { + fast_alpha_t& a = tabsixi[jtype]; + evdwl = r6inv*(a.lj3*r6inv-a.lj4); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (tmp_coef2 + 2.0*rsq) * tmp_coef1; + evdwl *= switch1; + } + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz); + } + } + } + + ff[i].x += tmpfx; + ff[i].y += tmpfy; + ff[i].z += tmpfz; + } + + free(fast_alpha); fast_alpha = 0; + + if (vflag_fdotr) virial_fdotr_compute(); +} + diff --git a/src/OPT/pair_lj_charmm_coul_long_opt.h b/src/OPT/pair_lj_charmm_coul_long_opt.h index c6616b0c0b..e2cc1af8ed 100644 --- a/src/OPT/pair_lj_charmm_coul_long_opt.h +++ b/src/OPT/pair_lj_charmm_coul_long_opt.h @@ -11,13 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: - James Fischer, High Performance Technologies, Inc. - David Richie, Stone Ridge Technology - Vincent Natol, Stone Ridge Technology -------------------------------------------------------------------------- */ - #ifdef PAIR_CLASS PairStyle(lj/charmm/coul/long/opt,PairLJCharmmCoulLongOpt) @@ -27,26 +20,10 @@ PairStyle(lj/charmm/coul/long/opt,PairLJCharmmCoulLongOpt) #ifndef LMP_PAIR_LJ_CHARMM_COUL_LONG_OPT_H #define LMP_PAIR_LJ_CHARMM_COUL_LONG_OPT_H -#include "math.h" -#include "stdlib.h" #include "pair_lj_charmm_coul_long.h" -#include "atom.h" -#include "force.h" -#include "neigh_list.h" namespace LAMMPS_NS { -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define EWALD_A1 0.254829592 -#define EWALD_A2 -0.284496736 -#define EWALD_A3 1.421413741 -#define EWALD_A4 -1.453152027 -#define EWALD_A5 1.061405429 - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - class PairLJCharmmCoulLongOpt : public PairLJCharmmCoulLong { public: PairLJCharmmCoulLongOpt(class LAMMPS *); @@ -55,292 +32,6 @@ class PairLJCharmmCoulLongOpt : public PairLJCharmmCoulLong { private: template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval(); }; - -template < int EVFLAG, int EFLAG, int NEWTON_PAIR > -void PairLJCharmmCoulLongOpt::eval() -{ - typedef struct { double x,y,z; } vec3_t; - - typedef struct { - double cutsq,lj1,lj2,lj3,lj4,offset; - double _pad[2]; - } fast_alpha_t; - - int i,j,ii,jj,inum,jnum,itype,jtype,itable,sbindex; - double fraction,table; - double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double philj,switch1,switch2; - - double rsq; - - double evdwl = 0.0; - double ecoul = 0.0; - - double** __restrict__ x = atom->x; - double** __restrict__ f = atom->f; - double* __restrict__ q = atom->q; - int* __restrict__ type = atom->type; - int nlocal = atom->nlocal; - double* __restrict__ special_coul = force->special_coul; - double* __restrict__ special_lj = force->special_lj; - double qqrd2e = force->qqrd2e; - - inum = list->inum; - int* __restrict__ ilist = list->ilist; - int** __restrict__ firstneigh = list->firstneigh; - int* __restrict__ numneigh = list->numneigh; - - vec3_t* __restrict__ xx = (vec3_t*)x[0]; - vec3_t* __restrict__ ff = (vec3_t*)f[0]; - - int ntypes = atom->ntypes; - int ntypes2 = ntypes*ntypes; - - double tmp_coef1 = 1.0/denom_lj; - double tmp_coef2 = cut_ljsq - 3.0*cut_lj_innersq; - - fast_alpha_t* __restrict__ fast_alpha = - (fast_alpha_t*)malloc(ntypes2*sizeof(fast_alpha_t)); - for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { - fast_alpha_t& a = fast_alpha[i*ntypes+j]; - a.cutsq = cutsq[i+1][j+1]; - a.lj1 = lj1[i+1][j+1]; - a.lj2 = lj2[i+1][j+1]; - a.lj3 = lj3[i+1][j+1]; - a.lj4 = lj4[i+1][j+1]; - } - fast_alpha_t* __restrict__ tabsix = fast_alpha; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double qtmp = q[i]; - double xtmp = xx[i].x; - double ytmp = xx[i].y; - double ztmp = xx[i].z; - itype = type[i] - 1; - int* __restrict__ jlist = firstneigh[i]; - jnum = numneigh[i]; - - double tmpfx = 0.0; - double tmpfy = 0.0; - double tmpfz = 0.0; - - fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*) &tabsix[itype*ntypes]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - sbindex = sbmask(j); - - if (sbindex == 0) { - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - rsq = delx*delx + dely*dely + delz*delz; - double tmp_coef3 = qtmp*q[j]; - - if (rsq < cut_bothsq) { - r2inv = 1.0/rsq; - - forcecoul = 0.0; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * - (EWALD_A1+t*(EWALD_A2+t*(EWALD_A3+t*(EWALD_A4+t*EWALD_A5)))) * - expm2; - prefactor = qqrd2e * tmp_coef3/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - } else { - union_int_float_t rsq_lookup; - rsq_lookup.f = rsq; - itable = rsq_lookup.i & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = tmp_coef3 * table; - } - } - - forcelj = 0.0; - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - jtype = type[j] - 1; - fast_alpha_t& a = tabsixi[jtype]; - forcelj = r6inv * (a.lj1*r6inv - a.lj2); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (tmp_coef2 + 2.0*rsq) * tmp_coef1; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) * tmp_coef1; - philj = r6inv * (a.lj3*r6inv - a.lj4); - forcelj = forcelj*switch1 + philj*switch2; - } - } - - double fpair = (forcecoul + forcelj) * r2inv; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - ecoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - ecoul = tmp_coef3 * table; - } - } else ecoul = 0.0; - - if (rsq < cut_ljsq) { - fast_alpha_t& a = tabsixi[jtype]; - evdwl = r6inv*(a.lj3*r6inv-a.lj4); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (tmp_coef2 + 2.0*rsq) * tmp_coef1; - evdwl *= switch1; - } - } else evdwl = 0.0; - } - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,ecoul,fpair,delx,dely,delz); - } - - } else { - factor_lj = special_lj[sbindex]; - factor_coul = special_coul[sbindex]; - j &= NEIGHMASK; - - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - rsq = delx*delx + dely*dely + delz*delz; - double tmp_coef3 = qtmp*q[j]; - - if (rsq < cut_bothsq) { - r2inv = 1.0/rsq; - - forcecoul = 0.0; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * - (EWALD_A1+t*(EWALD_A2+t*(EWALD_A3+t*(EWALD_A4+t*EWALD_A5)))) * - expm2; - prefactor = qqrd2e * tmp_coef3/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) { - forcecoul -= (1.0-factor_coul)*prefactor; - } - } else { - union_int_float_t rsq_lookup; - rsq_lookup.f = rsq; - itable = rsq_lookup.i & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = tmp_coef3 * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = tmp_coef3 * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } - - forcelj = 0.0; - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - jtype = type[j] - 1; - fast_alpha_t& a = tabsixi[jtype]; - forcelj = r6inv * (a.lj1*r6inv - a.lj2); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (tmp_coef2 + 2.0*rsq) * tmp_coef1; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) * tmp_coef1; - fast_alpha_t& a = tabsixi[jtype]; - philj = r6inv * (a.lj3*r6inv - a.lj4); - forcelj = forcelj*switch1 + philj*switch2; - } - } - - double fpair = (forcecoul + factor_lj*forcelj) * r2inv; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - ecoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - ecoul = tmp_coef3 * table; - } - if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; - } else ecoul = 0.0; - - if (rsq < cut_ljsq) { - fast_alpha_t& a = tabsixi[jtype]; - evdwl = r6inv*(a.lj3*r6inv-a.lj4); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (tmp_coef2 + 2.0*rsq) * tmp_coef1; - evdwl *= switch1; - } - evdwl *= factor_lj; - } else evdwl = 0.0; - } - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,ecoul,fpair,delx,dely,delz); - } - } - } - - ff[i].x += tmpfx; - ff[i].y += tmpfy; - ff[i].z += tmpfz; - } - - free(fast_alpha); fast_alpha = 0; - - if (vflag_fdotr) virial_fdotr_compute(); -} - -#undef EWALD_F -#undef EWALD_P -#undef EWALD_A1 -#undef EWALD_A2 -#undef EWALD_A3 -#undef EWALD_A4 -#undef EWALD_A5 - -#undef MIN -#undef MAX } diff --git a/src/OPT/pair_lj_cut_opt.cpp b/src/OPT/pair_lj_cut_opt.cpp index d939727a59..8f855da566 100644 --- a/src/OPT/pair_lj_cut_opt.cpp +++ b/src/OPT/pair_lj_cut_opt.cpp @@ -18,7 +18,11 @@ Vincent Natoli, Stone Ridge Technology ------------------------------------------------------------------------- */ +#include "stdlib.h" #include "pair_lj_cut_opt.h" +#include "atom.h" +#include "force.h" +#include "neigh_list.h" using namespace LAMMPS_NS; @@ -46,3 +50,152 @@ void PairLJCutOpt::compute(int eflag, int vflag) else return eval<0,0,0>(); } } + +/* ---------------------------------------------------------------------- */ + +template < int EVFLAG, int EFLAG, int NEWTON_PAIR > +void PairLJCutOpt::eval() +{ + typedef struct { double x,y,z; } vec3_t; + + typedef struct { + double cutsq,lj1,lj2,lj3,lj4,offset; + double _pad[2]; + } fast_alpha_t; + + int i,j,ii,jj,inum,jnum,itype,jtype,sbindex; + double factor_lj; + double evdwl = 0.0; + + double** __restrict__ x = atom->x; + double** __restrict__ f = atom->f; + int* __restrict__ type = atom->type; + int nlocal = atom->nlocal; + double* __restrict__ special_lj = force->special_lj; + + inum = list->inum; + int* __restrict__ ilist = list->ilist; + int** __restrict__ firstneigh = list->firstneigh; + int* __restrict__ numneigh = list->numneigh; + + vec3_t* __restrict__ xx = (vec3_t*)x[0]; + vec3_t* __restrict__ ff = (vec3_t*)f[0]; + + int ntypes = atom->ntypes; + int ntypes2 = ntypes*ntypes; + + fast_alpha_t* __restrict__ fast_alpha = + (fast_alpha_t*) malloc(ntypes2*sizeof(fast_alpha_t)); + for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { + fast_alpha_t& a = fast_alpha[i*ntypes+j]; + a.cutsq = cutsq[i+1][j+1]; + a.lj1 = lj1[i+1][j+1]; + a.lj2 = lj2[i+1][j+1]; + a.lj3 = lj3[i+1][j+1]; + a.lj4 = lj4[i+1][j+1]; + a.offset = offset[i+1][j+1]; + } + fast_alpha_t* __restrict__ tabsix = fast_alpha; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double xtmp = xx[i].x; + double ytmp = xx[i].y; + double ztmp = xx[i].z; + itype = type[i] - 1; + int* __restrict__ jlist = firstneigh[i]; + jnum = numneigh[i]; + + double tmpfx = 0.0; + double tmpfy = 0.0; + double tmpfz = 0.0; + + fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*)&tabsix[itype*ntypes]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + sbindex = sbmask(j); + + if (sbindex == 0) { + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + jtype = type[j] - 1; + + fast_alpha_t& a = tabsixi[jtype]; + + if (rsq < a.cutsq) { + double r2inv = 1.0/rsq; + double r6inv = r2inv*r2inv*r2inv; + double forcelj = r6inv * (a.lj1*r6inv - a.lj2); + double fpair = forcelj*r2inv; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset; + + if (EVFLAG) + ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz); + } + + } else { + factor_lj = special_lj[sbindex]; + j &= NEIGHMASK; + + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + int jtype1 = type[j]; + jtype = jtype1 - 1; + + fast_alpha_t& a = tabsixi[jtype]; + if (rsq < a.cutsq) { + double r2inv = 1.0/rsq; + double r6inv = r2inv*r2inv*r2inv; + fast_alpha_t& a = tabsixi[jtype]; + double forcelj = r6inv * (a.lj1*r6inv - a.lj2); + double fpair = factor_lj*forcelj*r2inv; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz); + } + } + } + + ff[i].x += tmpfx; + ff[i].y += tmpfy; + ff[i].z += tmpfz; + } + + free(fast_alpha); fast_alpha = 0; + + if (vflag_fdotr) virial_fdotr_compute(); +} diff --git a/src/OPT/pair_lj_cut_opt.h b/src/OPT/pair_lj_cut_opt.h index acd6afefeb..0bdd004811 100644 --- a/src/OPT/pair_lj_cut_opt.h +++ b/src/OPT/pair_lj_cut_opt.h @@ -11,13 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: - James Fischer, High Performance Technologies, Inc. - David Richie, Stone Ridge Technology - Vincent Natol, Stone Ridge Technology -------------------------------------------------------------------------- */ - #ifdef PAIR_CLASS PairStyle(lj/cut/opt,PairLJCutOpt) @@ -27,11 +20,7 @@ PairStyle(lj/cut/opt,PairLJCutOpt) #ifndef LMP_PAIR_LJ_CUT_OPT_H #define LMP_PAIR_LJ_CUT_OPT_H -#include "stdlib.h" #include "pair_lj_cut.h" -#include "atom.h" -#include "force.h" -#include "neigh_list.h" namespace LAMMPS_NS { @@ -44,153 +33,6 @@ class PairLJCutOpt : public PairLJCut { template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval(); }; -template < int EVFLAG, int EFLAG, int NEWTON_PAIR > -void PairLJCutOpt::eval() -{ - typedef struct { double x,y,z; } vec3_t; - - typedef struct { - double cutsq,lj1,lj2,lj3,lj4,offset; - double _pad[2]; - } fast_alpha_t; - - int i,j,ii,jj,inum,jnum,itype,jtype,sbindex; - double factor_lj; - double evdwl = 0.0; - - double** __restrict__ x = atom->x; - double** __restrict__ f = atom->f; - int* __restrict__ type = atom->type; - int nlocal = atom->nlocal; - double* __restrict__ special_lj = force->special_lj; - - inum = list->inum; - int* __restrict__ ilist = list->ilist; - int** __restrict__ firstneigh = list->firstneigh; - int* __restrict__ numneigh = list->numneigh; - - vec3_t* __restrict__ xx = (vec3_t*)x[0]; - vec3_t* __restrict__ ff = (vec3_t*)f[0]; - - int ntypes = atom->ntypes; - int ntypes2 = ntypes*ntypes; - - fast_alpha_t* __restrict__ fast_alpha = - (fast_alpha_t*) malloc(ntypes2*sizeof(fast_alpha_t)); - for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { - fast_alpha_t& a = fast_alpha[i*ntypes+j]; - a.cutsq = cutsq[i+1][j+1]; - a.lj1 = lj1[i+1][j+1]; - a.lj2 = lj2[i+1][j+1]; - a.lj3 = lj3[i+1][j+1]; - a.lj4 = lj4[i+1][j+1]; - a.offset = offset[i+1][j+1]; - } - fast_alpha_t* __restrict__ tabsix = fast_alpha; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double xtmp = xx[i].x; - double ytmp = xx[i].y; - double ztmp = xx[i].z; - itype = type[i] - 1; - int* __restrict__ jlist = firstneigh[i]; - jnum = numneigh[i]; - - double tmpfx = 0.0; - double tmpfy = 0.0; - double tmpfz = 0.0; - - fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*)&tabsix[itype*ntypes]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - sbindex = sbmask(j); - - if (sbindex == 0) { - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - jtype = type[j] - 1; - - fast_alpha_t& a = tabsixi[jtype]; - - if (rsq < a.cutsq) { - double r2inv = 1.0/rsq; - double r6inv = r2inv*r2inv*r2inv; - double forcelj = r6inv * (a.lj1*r6inv - a.lj2); - double fpair = forcelj*r2inv; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset; - - if (EVFLAG) - ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,0.0,fpair,delx,dely,delz); - } - - } else { - factor_lj = special_lj[sbindex]; - j &= NEIGHMASK; - - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - int jtype1 = type[j]; - jtype = jtype1 - 1; - - fast_alpha_t& a = tabsixi[jtype]; - if (rsq < a.cutsq) { - double r2inv = 1.0/rsq; - double r6inv = r2inv*r2inv*r2inv; - fast_alpha_t& a = tabsixi[jtype]; - double forcelj = r6inv * (a.lj1*r6inv - a.lj2); - double fpair = factor_lj*forcelj*r2inv; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) { - evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset; - evdwl *= factor_lj; - } - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,0.0,fpair,delx,dely,delz); - } - } - } - - ff[i].x += tmpfx; - ff[i].y += tmpfy; - ff[i].z += tmpfz; - } - - free(fast_alpha); fast_alpha = 0; - - if (vflag_fdotr) virial_fdotr_compute(); -} - } #endif diff --git a/src/OPT/pair_morse_opt.cpp b/src/OPT/pair_morse_opt.cpp index 1cf96d85b4..5a9bfe7bed 100644 --- a/src/OPT/pair_morse_opt.cpp +++ b/src/OPT/pair_morse_opt.cpp @@ -18,7 +18,12 @@ Vincent Natoli, Stone Ridge Technology ------------------------------------------------------------------------- */ +#include "math.h" +#include "stdlib.h" #include "pair_morse_opt.h" +#include "atom.h" +#include "force.h" +#include "neigh_list.h" using namespace LAMMPS_NS; @@ -46,3 +51,148 @@ void PairMorseOpt::compute(int eflag, int vflag) else return eval<0,0,0>(); } } + +/* ---------------------------------------------------------------------- */ + +template < int EVFLAG, int EFLAG, int NEWTON_PAIR > +void PairMorseOpt::eval() +{ + typedef struct { double x,y,z; } vec3_t; + + typedef struct { + double cutsq,r0,alpha,morse1,d0,offset; + double _pad[2]; + } fast_alpha_t; + + int i,j,ii,jj,inum,jnum,itype,jtype,sbindex; + double factor_lj; + double evdwl = 0.0; + + double** __restrict__ x = atom->x; + double** __restrict__ f = atom->f; + int* __restrict__ type = atom->type; + int nlocal = atom->nlocal; + double* __restrict__ special_lj = force->special_lj; + + inum = list->inum; + int* __restrict__ ilist = list->ilist; + int** __restrict__ firstneigh = list->firstneigh; + int* __restrict__ numneigh = list->numneigh; + + vec3_t* __restrict__ xx = (vec3_t*)x[0]; + vec3_t* __restrict__ ff = (vec3_t*)f[0]; + + int ntypes = atom->ntypes; + int ntypes2 = ntypes*ntypes; + + fast_alpha_t* __restrict__ fast_alpha = + (fast_alpha_t*) malloc(ntypes2*sizeof(fast_alpha_t)); + for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { + fast_alpha_t& a = fast_alpha[i*ntypes+j]; + a.cutsq = cutsq[i+1][j+1]; + a.r0 = r0[i+1][j+1]; + a.alpha = alpha[i+1][j+1]; + a.morse1 = morse1[i+1][j+1]; + a.d0 = d0[i+1][j+1]; + a.offset = offset[i+1][j+1]; + } + fast_alpha_t* __restrict__ tabsix = fast_alpha; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + double xtmp = xx[i].x; + double ytmp = xx[i].y; + double ztmp = xx[i].z; + itype = type[i] - 1; + int* __restrict__ jlist = firstneigh[i]; + jnum = numneigh[i]; + + double tmpfx = 0.0; + double tmpfy = 0.0; + double tmpfz = 0.0; + + fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*)&tabsix[itype*ntypes]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + sbindex = sbmask(j); + + if (sbindex == 0) { + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + jtype = type[j] - 1; + + fast_alpha_t& a = tabsixi[jtype]; + if (rsq < a.cutsq) { + double r = sqrt(rsq); + double dr = r - a.r0; + double dexp = exp(-a.alpha * dr); + double fpair = a.morse1 * (dexp*dexp - dexp) / r; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz); + } + + } else { + factor_lj = special_lj[sbindex]; + j &= NEIGHMASK; + + double delx = xtmp - xx[j].x; + double dely = ytmp - xx[j].y; + double delz = ztmp - xx[j].z; + double rsq = delx*delx + dely*dely + delz*delz; + + jtype = type[j] - 1; + + fast_alpha_t& a = tabsixi[jtype]; + if (rsq < a.cutsq) { + double r = sqrt(rsq); + double dr = r - a.r0; + double dexp = exp(-a.alpha * dr); + double fpair = factor_lj * a.morse1 * (dexp*dexp - dexp) / r; + + tmpfx += delx*fpair; + tmpfy += dely*fpair; + tmpfz += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + ff[j].x -= delx*fpair; + ff[j].y -= dely*fpair; + ff[j].z -= delz*fpair; + } + + if (EFLAG) { + evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz); + } + } + } + + ff[i].x += tmpfx; + ff[i].y += tmpfy; + ff[i].z += tmpfz; + } + + free(fast_alpha); fast_alpha = 0; + + if (vflag_fdotr) virial_fdotr_compute(); +} diff --git a/src/OPT/pair_morse_opt.h b/src/OPT/pair_morse_opt.h index 3d1ea371c6..0e80ac4d74 100644 --- a/src/OPT/pair_morse_opt.h +++ b/src/OPT/pair_morse_opt.h @@ -11,13 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: - James Fischer, High Performance Technologies, Inc. - David Richie, Stone Ridge Technology - Vincent Natol, Stone Ridge Technology -------------------------------------------------------------------------- */ - #ifdef PAIR_CLASS PairStyle(morse/opt,PairMorseOpt) @@ -27,12 +20,7 @@ PairStyle(morse/opt,PairMorseOpt) #ifndef LMP_PAIR_MORSE_OPT_H #define LMP_PAIR_MORSE_OPT_H -#include "math.h" -#include "stdlib.h" #include "pair_morse.h" -#include "atom.h" -#include "force.h" -#include "neigh_list.h" namespace LAMMPS_NS { @@ -45,149 +33,6 @@ class PairMorseOpt : public PairMorse { template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval(); }; -template < int EVFLAG, int EFLAG, int NEWTON_PAIR > -void PairMorseOpt::eval() -{ - typedef struct { double x,y,z; } vec3_t; - - typedef struct { - double cutsq,r0,alpha,morse1,d0,offset; - double _pad[2]; - } fast_alpha_t; - - int i,j,ii,jj,inum,jnum,itype,jtype,sbindex; - double factor_lj; - double evdwl = 0.0; - - double** __restrict__ x = atom->x; - double** __restrict__ f = atom->f; - int* __restrict__ type = atom->type; - int nlocal = atom->nlocal; - double* __restrict__ special_lj = force->special_lj; - - inum = list->inum; - int* __restrict__ ilist = list->ilist; - int** __restrict__ firstneigh = list->firstneigh; - int* __restrict__ numneigh = list->numneigh; - - vec3_t* __restrict__ xx = (vec3_t*)x[0]; - vec3_t* __restrict__ ff = (vec3_t*)f[0]; - - int ntypes = atom->ntypes; - int ntypes2 = ntypes*ntypes; - - fast_alpha_t* __restrict__ fast_alpha = - (fast_alpha_t*) malloc(ntypes2*sizeof(fast_alpha_t)); - for (i = 0; i < ntypes; i++) for (j = 0; j < ntypes; j++) { - fast_alpha_t& a = fast_alpha[i*ntypes+j]; - a.cutsq = cutsq[i+1][j+1]; - a.r0 = r0[i+1][j+1]; - a.alpha = alpha[i+1][j+1]; - a.morse1 = morse1[i+1][j+1]; - a.d0 = d0[i+1][j+1]; - a.offset = offset[i+1][j+1]; - } - fast_alpha_t* __restrict__ tabsix = fast_alpha; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - double xtmp = xx[i].x; - double ytmp = xx[i].y; - double ztmp = xx[i].z; - itype = type[i] - 1; - int* __restrict__ jlist = firstneigh[i]; - jnum = numneigh[i]; - - double tmpfx = 0.0; - double tmpfy = 0.0; - double tmpfz = 0.0; - - fast_alpha_t* __restrict__ tabsixi = (fast_alpha_t*)&tabsix[itype*ntypes]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - sbindex = sbmask(j); - - if (sbindex == 0) { - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - jtype = type[j] - 1; - - fast_alpha_t& a = tabsixi[jtype]; - if (rsq < a.cutsq) { - double r = sqrt(rsq); - double dr = r - a.r0; - double dexp = exp(-a.alpha * dr); - double fpair = a.morse1 * (dexp*dexp - dexp) / r; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,0.0,fpair,delx,dely,delz); - } - - } else { - factor_lj = special_lj[sbindex]; - j &= NEIGHMASK; - - double delx = xtmp - xx[j].x; - double dely = ytmp - xx[j].y; - double delz = ztmp - xx[j].z; - double rsq = delx*delx + dely*dely + delz*delz; - - jtype = type[j] - 1; - - fast_alpha_t& a = tabsixi[jtype]; - if (rsq < a.cutsq) { - double r = sqrt(rsq); - double dr = r - a.r0; - double dexp = exp(-a.alpha * dr); - double fpair = factor_lj * a.morse1 * (dexp*dexp - dexp) / r; - - tmpfx += delx*fpair; - tmpfy += dely*fpair; - tmpfz += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { - ff[j].x -= delx*fpair; - ff[j].y -= dely*fpair; - ff[j].z -= delz*fpair; - } - - if (EFLAG) { - evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; - evdwl *= factor_lj; - } - - if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR, - evdwl,0.0,fpair,delx,dely,delz); - } - } - } - - ff[i].x += tmpfx; - ff[i].y += tmpfy; - ff[i].z += tmpfz; - } - - free(fast_alpha); fast_alpha = 0; - - if (vflag_fdotr) virial_fdotr_compute(); -} - } #endif From 89f00f3011d5f3fa04ec6c4b12d6daf0ca7c6b01 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 17:09:02 +0000 Subject: [PATCH 005/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6761 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/Install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/SHOCK/Install.sh b/src/SHOCK/Install.sh index 642f0839c5..84f40ddf72 100644 --- a/src/SHOCK/Install.sh +++ b/src/SHOCK/Install.sh @@ -2,14 +2,18 @@ if (test $1 = 1) then - cp fix_msst.cpp fix_nphug.cpp .. + cp fix_msst.cpp .. + cp fix_nphug.cpp .. - cp fix_msst.h fix_nphug.h .. + cp fix_msst.h .. + cp fix_nphug.h .. elif (test $1 = 0) then - rm -f ../fix_msst.cpp ../fix_nphug.cpp + rm -f ../fix_msst.cpp + rm -f ../fix_nphug.cpp - rm -f ../fix_msst.h ../fix_nphug.h + rm -f ../fix_msst.h + rm -f ../fix_nphug.h fi From 84261163c08d3db2b9eb8db66b132139b09e2b94 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 20:58:20 +0000 Subject: [PATCH 006/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6762 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_accelerate.html | 8 ++++---- doc/Section_accelerate.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html index 069462f569..3cee8b43ab 100644 --- a/doc/Section_accelerate.html +++ b/doc/Section_accelerate.html @@ -74,10 +74,10 @@ and kspace sections. packages, since they are both designed to use NVIDIA GPU hardware.

10.1 OPT package
-10.5 USER-OMP package
-10.2 GPU package
-10.3 USER-CUDA package
-10.4 Comparison of GPU and USER-CUDA packages
+10.2 USER-OMP package
+10.3 GPU package
+10.4 USER-CUDA package
+10.5 Comparison of GPU and USER-CUDA packages

diff --git a/doc/Section_accelerate.txt b/doc/Section_accelerate.txt index 0babffd31a..f18745e31f 100644 --- a/doc/Section_accelerate.txt +++ b/doc/Section_accelerate.txt @@ -71,10 +71,10 @@ The final section compares and contrasts the GPU and USER-CUDA packages, since they are both designed to use NVIDIA GPU hardware. 10.1 "OPT package"_#10_1 -10.5 "USER-OMP package"_#10_2 -10.2 "GPU package"_#10_3 -10.3 "USER-CUDA package"_#10_4 -10.4 "Comparison of GPU and USER-CUDA packages"_#10_4 :all(b) +10.2 "USER-OMP package"_#10_2 +10.3 "GPU package"_#10_3 +10.4 "USER-CUDA package"_#10_4 +10.5 "Comparison of GPU and USER-CUDA packages"_#10_4 :all(b) :line :line From a3a957195a1b0d8092bdd41fe5433f2e6e47ef81 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 20:58:36 +0000 Subject: [PATCH 007/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6763 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/Makefile.lammps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps index d4f3bc58ed..3a5cd938dc 100644 --- a/lib/cuda/Makefile.lammps +++ b/lib/cuda/Makefile.lammps @@ -1,6 +1,6 @@ # Settings that the LAMMPS build will import when this package library is used -CUDA_INSATLL_PATH = /usr/local/cuda-3.2 +CUDA_INSATLL_PATH = /usr/local/cuda CUDA_USRLIB_CONDITIONAL = user-cuda_SYSINC = -I$(CUDA_INSTALL_PATH)/include From c120ad3313c6aa6c21ff6eb8a44908510bb570e8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:11:24 +0000 Subject: [PATCH 008/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6764 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 21 +++++++++++---------- doc/Section_commands.txt | 1 + doc/pair_coul.html | 26 ++++++++++++++++++++++++++ doc/pair_coul.txt | 26 +++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 0618a5d250..3671b787b1 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -442,16 +442,17 @@ package.
- - - - - - - - - - + + + + + + + + + +
born/coul/long/cudabuck/coul/cut/cudabuck/coul/long/cudabuck/cuda
cg/cmm/coul/cut/cudacg/cmm/coul/debye/cudacg/cmm/coul/long/cudacg/cmm/coul/long/gpu
cg/cmm/cudacg/cmm/gpueam/alloy/cudaeam/alloy/opt
eam/cudaeam/fs/cudaeam/fs/opteam/opt
gayberne/gpugran/hooke/cudalj/charmm/coul/charmm/cudalj/charmm/coul/charmm/implicit/cuda
lj/charmm/coul/long/cudalj/charmm/coul/long/gpulj/charmm/coul/long/optlj/class2/coul/cut/cuda
lj/class2/coul/long/cudalj/class2/coul/long/gpulj/class2/cudalj/class2/gpu
lj/cut/coul/cut/cudalj/cut/coul/cut/gpulj/cut/coul/debye/cudalj/cut/coul/long/cuda
lj/cut/coul/long/gpulj/cut/cudalj/cut/experimental/cudalj/cut/gpu
lj/cut/optlj/expand/cudalj/expand/gpulj/gromacs/coul/gromacs/cuda
lj/gromacs/cudalj/smooth/cudalj96/cut/cudalj96/cut/gpu
morse/cudamorse/gpumorse/optresquared/gpu +
cg/cmm/cudacg/cmm/gpucoul/long/gpueam/alloy/cuda
eam/alloy/opteam/cudaeam/fs/cudaeam/fs/opt
eam/optgayberne/gpugran/hooke/cudalj/charmm/coul/charmm/cuda
lj/charmm/coul/charmm/implicit/cudalj/charmm/coul/long/cudalj/charmm/coul/long/gpulj/charmm/coul/long/opt
lj/class2/coul/cut/cudalj/class2/coul/long/cudalj/class2/coul/long/gpulj/class2/cuda
lj/class2/gpulj/cut/coul/cut/cudalj/cut/coul/cut/gpulj/cut/coul/debye/cuda
lj/cut/coul/long/cudalj/cut/coul/long/gpulj/cut/cudalj/cut/experimental/cuda
lj/cut/gpulj/cut/optlj/expand/cudalj/expand/gpu
lj/gromacs/coul/gromacs/cudalj/gromacs/cudalj/smooth/cudalj96/cut/cuda
lj96/cut/gpumorse/cudamorse/gpumorse/opt
resquared/gpu

diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index f9b9b1a189..8bc22c3a49 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -686,6 +686,7 @@ package"_Section_accelerate.html. "cg/cmm/coul/long/gpu"_pair_cmm.html, "cg/cmm/cuda"_pair_cmm.html, "cg/cmm/gpu"_pair_cmm.html, +"coul/long/gpu"_pair_coul.html, "eam/alloy/cuda"_pair_eam.html, "eam/alloy/opt"_pair_eam.html, "eam/cuda"_pair_eam.html, diff --git a/doc/pair_coul.html b/doc/pair_coul.html index 3cdc20760b..2d3b2f623d 100644 --- a/doc/pair_coul.html +++ b/doc/pair_coul.html @@ -15,12 +15,16 @@

pair_style coul/long command

+

pair_style coul/long/gpu command +

Syntax:

pair_style coul/cut cutoff
 pair_style coul/debye kappa cutoff
 pair_style coul/long cutoff 
 
+
pair_style coul/long/gpu cutoff 
+
  • cutoff = global cutoff for Coulombic interactions
  • kappa = Debye length (inverse distance units)
@@ -89,6 +93,28 @@ Coulombic cutoff specified in the pair_style command.


+

Styles with a cuda, gpu, or opt suffix are functionally the same +as the corresponding style without the suffix. They have been +optimized to run faster, depending on your available hardware, as +discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

+

These accelerated styles are part of the "user-cuda", "gpu", and "opt" +packages respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

+

You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can use +the suffix command in your input script. +

+

See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

+
+

Mixing, shift, table, tail correction, restart, rRESPA info:

For atom type pairs I,J and I != J, the cutoff distance for the diff --git a/doc/pair_coul.txt b/doc/pair_coul.txt index d906461547..a51a3e15cd 100644 --- a/doc/pair_coul.txt +++ b/doc/pair_coul.txt @@ -9,12 +9,14 @@ pair_style coul/cut command :h3 pair_style coul/debye command :h3 pair_style coul/long command :h3 +pair_style coul/long/gpu command :h3 [Syntax:] pair_style coul/cut cutoff pair_style coul/debye kappa cutoff -pair_style coul/long cutoff :pre +pair_style coul/long cutoff +pair_style coul/long/gpu cutoff :pre cutoff = global cutoff for Coulombic interactions kappa = Debye length (inverse distance units) :ul @@ -84,6 +86,28 @@ Coulombic cutoff specified in the pair_style command. :line +Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same +as the corresponding style without the suffix. They have been +optimized to run faster, depending on your available hardware, as +discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the "user-cuda", "gpu", and "opt" +packages respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#2_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#2_6 when you invoke LAMMPS, or you can use +the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the cutoff distance for the From 7a1f6fc1ee186a10d4464ab13451218471a1fc54 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:11:35 +0000 Subject: [PATCH 009/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6765 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/gpu/Nvidia.makefile | 14 ++++++++++++++ lib/gpu/README | 17 ++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/gpu/Nvidia.makefile b/lib/gpu/Nvidia.makefile index 1776cb44a9..b126f3433a 100644 --- a/lib/gpu/Nvidia.makefile +++ b/lib/gpu/Nvidia.makefile @@ -54,6 +54,7 @@ OBJS = $(OBJ_DIR)/pair_gpu_atom.o $(OBJ_DIR)/pair_gpu_ans.o \ $(OBJ_DIR)/ljc_cut_gpu_memory.o $(OBJ_DIR)/ljc_cut_gpu.o \ $(OBJ_DIR)/ljcl_cut_gpu_memory.o $(OBJ_DIR)/ljcl_cut_gpu.o \ $(OBJ_DIR)/lj_class2_long.o $(OBJ_DIR)/lj_class2_long_ext.o \ + $(OBJ_DIR)/coul_long_gpu_memory.o $(OBJ_DIR)/coul_long_gpu.o \ $(OBJ_DIR)/morse_gpu_memory.o $(OBJ_DIR)/morse_gpu.o \ $(OBJ_DIR)/crml_gpu_memory.o $(OBJ_DIR)/crml_gpu.o \ $(OBJ_DIR)/cmm_cut_gpu_memory.o $(OBJ_DIR)/cmm_cut_gpu.o \ @@ -76,6 +77,7 @@ PTXS = $(OBJ_DIR)/pair_gpu_dev_kernel.ptx \ $(OBJ_DIR)/ljc_cut_gpu_kernel.ptx $(OBJ_DIR)/ljc_cut_gpu_ptx.h \ $(OBJ_DIR)/ljcl_cut_gpu_kernel.ptx $(OBJ_DIR)/ljcl_cut_gpu_ptx.h \ $(OBJ_DIR)/lj_class2_long.ptx $(OBJ_DIR)/lj_class2_long_ptx.h \ + $(OBJ_DIR)/coul_long_gpu_kernel.ptx $(OBJ_DIR)/coul_long_gpu_ptx.h \ $(OBJ_DIR)/morse_gpu_kernel.ptx $(OBJ_DIR)/morse_gpu_ptx.h \ $(OBJ_DIR)/crml_gpu_kernel.ptx $(OBJ_DIR)/crml_gpu_ptx.h \ $(OBJ_DIR)/cmm_cut_gpu_kernel.ptx $(OBJ_DIR)/cmm_cut_gpu_ptx.h \ @@ -252,6 +254,18 @@ $(OBJ_DIR)/ljcl_cut_gpu_memory.o: $(ALL_H) ljcl_cut_gpu_memory.h ljcl_cut_gpu_me $(OBJ_DIR)/ljcl_cut_gpu.o: $(ALL_H) ljcl_cut_gpu_memory.h ljcl_cut_gpu.cpp charge_gpu_memory.h $(CUDR) -o $@ -c ljcl_cut_gpu.cpp -I$(OBJ_DIR) +$(OBJ_DIR)/coul_long_gpu_kernel.ptx: coul_long_gpu_kernel.cu pair_gpu_precision.h + $(CUDA) --ptx -DNV_KERNEL -o $@ coul_long_gpu_kernel.cu + +$(OBJ_DIR)/coul_long_gpu_ptx.h: $(OBJ_DIR)/coul_long_gpu_kernel.ptx $(OBJ_DIR)/coul_long_gpu_kernel.ptx + $(BSH) ./geryon/file_to_cstr.sh $(OBJ_DIR)/coul_long_gpu_kernel.ptx $(OBJ_DIR)/coul_long_gpu_ptx.h + +$(OBJ_DIR)/coul_long_gpu_memory.o: $(ALL_H) coul_long_gpu_memory.h coul_long_gpu_memory.cpp $(OBJ_DIR)/coul_long_gpu_ptx.h $(OBJ_DIR)/charge_gpu_memory.o + $(CUDR) -o $@ -c coul_long_gpu_memory.cpp -I$(OBJ_DIR) + +$(OBJ_DIR)/coul_long_gpu.o: $(ALL_H) coul_long_gpu_memory.h coul_long_gpu.cpp charge_gpu_memory.h + $(CUDR) -o $@ -c coul_long_gpu.cpp -I$(OBJ_DIR) + $(OBJ_DIR)/morse_gpu_kernel.ptx: morse_gpu_kernel.cu pair_gpu_precision.h $(CUDA) --ptx -DNV_KERNEL -o $@ morse_gpu_kernel.cu diff --git a/lib/gpu/README b/lib/gpu/README index 5f6637a9c4..61486b0d15 100644 --- a/lib/gpu/README +++ b/lib/gpu/README @@ -53,8 +53,9 @@ Current pair styles supporting GPU acceleration: 7. morse 8. cg/cmm 9. cg/cmm/coul/long - 10. gayberne - 11. pppm + 10. coul/long + 11. gayberne + 12. pppm MULTIPLE LAMMPS PROCESSES @@ -68,7 +69,7 @@ LAMMPS user manual for details on running with GPU acceleration. BUILDING AND PRECISION MODES To build, edit the CUDA_ARCH, CUDA_PRECISION, CUDA_HOME variables in one of -the Makefiles. CUDA_ARCH should be set based on the compute capability of +the Makefiles. CUDA_ARCH should be set based on the compute capability of your GPU. This can be verified by running the nvc_get_devices executable after the build is complete. Additionally, the GPU package must be installed and compiled for LAMMPS. This may require editing the gpu_SYSPATH variable in the @@ -100,10 +101,11 @@ NOTE: Double precision is only supported on certain GPUs (with with -DFFT_SINGLE. For details on configuring FFT support in LAMMPS, see http://lammps.sandia.gov/doc/Section_start.html#2_2_4 -NOTE: For Tesla and other graphics cards with compute capability>=1.3, +NOTE: For graphics cards with compute capability>=1.3 (e.g. Tesla C1060), make sure that -arch=sm_13 is set on the CUDA_ARCH line. -NOTE: For Fermi, make sure that -arch=sm_20 is set on the CUDA_ARCH line. +NOTE: For newer graphics card (a.k.a. "Fermi", e.g. Tesla C2050), make + sure that -arch=sm_20 is set on the CUDA_ARCH line. NOTE: The gayberne/gpu pair style will only be installed if the ASPHERE package has been installed. @@ -111,8 +113,9 @@ NOTE: The gayberne/gpu pair style will only be installed if the ASPHERE NOTE: The cg/cmm/gpu and cg/cmm/coul/long/gpu pair styles will only be installed if the USER-CG-CMM package has been installed. -NOTE: The lj/cut/coul/long/gpu, cg/cmm/coul/long/gpu, and pppm/gpu styles - will only be installed if the KSPACE package has been installed. +NOTE: The lj/cut/coul/long/gpu, cg/cmm/coul/long/gpu, coul/long/gpu, + and pppm/gpu styles will only be installed if the KSPACE package + has been installed. NOTE: The lj/charmm/coul/long will only be installed if the MOLECULE package has been installed. From 541c47f4d45df954467efc37aab211ff65174e79 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:12:16 +0000 Subject: [PATCH 010/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6766 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/gpu/coul_long_gpu.cpp | 124 ++++++++++ lib/gpu/coul_long_gpu_kernel.cu | 411 +++++++++++++++++++++++++++++++ lib/gpu/coul_long_gpu_memory.cpp | 158 ++++++++++++ lib/gpu/coul_long_gpu_memory.h | 79 ++++++ 4 files changed, 772 insertions(+) create mode 100644 lib/gpu/coul_long_gpu.cpp create mode 100644 lib/gpu/coul_long_gpu_kernel.cu create mode 100644 lib/gpu/coul_long_gpu_memory.cpp create mode 100644 lib/gpu/coul_long_gpu_memory.h diff --git a/lib/gpu/coul_long_gpu.cpp b/lib/gpu/coul_long_gpu.cpp new file mode 100644 index 0000000000..60c0d35d7d --- /dev/null +++ b/lib/gpu/coul_long_gpu.cpp @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Mike Brown (ORNL), brownw@ornl.gov +------------------------------------------------------------------------- */ + +#include +#include +#include + +#include "coul_long_gpu_memory.h" + +using namespace std; + +static CL_GPU_Memory CLMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int cl_gpu_init(const int inum, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, int &gpu_mode, + FILE *screen, double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald) { + CLMF.clear(); + gpu_mode=CLMF.device->gpu_mode(); + double gpu_split=CLMF.device->particle_split(); + int first_gpu=CLMF.device->first_device(); + int last_gpu=CLMF.device->last_device(); + int world_me=CLMF.device->world_me(); + int gpu_rank=CLMF.device->gpu_rank(); + int procs_per_gpu=CLMF.device->procs_per_gpu(); + + CLMF.device->init_message(screen,"coul/long",first_gpu,last_gpu); + + bool message=false; + if (CLMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing GPU and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=CLMF.init(inum, nall, 300, maxspecial, cell_size, gpu_split, + screen, host_cut_coulsq, host_special_coul, qqrd2e, + g_ewald); + + CLMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; igpu_barrier(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + CLMF.estimate_gpu_overhead(); + return init_ok; +} + +void cl_gpu_clear() { + CLMF.clear(); +} + +int** cl_gpu_compute_n(const int ago, const int inum_full, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, int *tag, int **nspecial, + int **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success, double *host_q, double *boxlo, + double *prd) { + return CLMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_q, boxlo, prd); +} + +void cl_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, + const int nlocal, double *boxlo, double *prd) { + CLMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj, + firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success, + host_q,nlocal,boxlo,prd); +} + +double cl_gpu_bytes() { + return CLMF.host_memory_usage(); +} + + diff --git a/lib/gpu/coul_long_gpu_kernel.cu b/lib/gpu/coul_long_gpu_kernel.cu new file mode 100644 index 0000000000..bc3747a7e3 --- /dev/null +++ b/lib/gpu/coul_long_gpu_kernel.cu @@ -0,0 +1,411 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Mike Brown (ORNL), brownw@ornl.gov +------------------------------------------------------------------------- */ + +#ifndef CL_GPU_KERNEL +#define CL_GPU_KERNEL + +#ifdef NV_KERNEL + +#include "nv_kernel_def.h" +texture pos_tex; +texture q_tex; + +#ifdef _DOUBLE_DOUBLE +__inline double4 fetch_pos(const int& i, const double4 *pos) +{ + return pos[i]; +} +__inline double fetch_q(const int& i, const double *q) +{ + return q[i]; +} +#else +__inline float4 fetch_pos(const int& i, const float4 *pos) +{ + return tex1Dfetch(pos_tex, i); +} +__inline float fetch_q(const int& i, const float *q) +{ + return tex1Dfetch(q_tex, i); +} +#endif + +#else + +#pragma OPENCL EXTENSION cl_khr_fp64: enable +#define GLOBAL_ID_X get_global_id(0) +#define THREAD_ID_X get_local_id(0) +#define BLOCK_ID_X get_group_id(0) +#define BLOCK_SIZE_X get_local_size(0) +#define __syncthreads() barrier(CLK_LOCAL_MEM_FENCE) +#define __inline inline + +#define fetch_pos(i,y) x_[i] +#define fetch_q(i,y) q_[i] +#define BLOCK_PAIR 64 +#define MAX_SHARED_TYPES 8 + +#endif + +#ifdef _DOUBLE_DOUBLE +#define numtyp double +#define numtyp2 double2 +#define numtyp4 double4 +#define acctyp double +#define acctyp4 double4 +#endif + +#ifdef _SINGLE_DOUBLE +#define numtyp float +#define numtyp2 float2 +#define numtyp4 float4 +#define acctyp double +#define acctyp4 double4 +#endif + +#ifndef numtyp +#define numtyp float +#define numtyp2 float2 +#define numtyp4 float4 +#define acctyp float +#define acctyp4 float4 +#endif + +#define EWALD_F (numtyp)1.12837917 +#define EWALD_P (numtyp)0.3275911 +#define A1 (numtyp)0.254829592 +#define A2 (numtyp)-0.284496736 +#define A3 (numtyp)1.421413741 +#define A4 (numtyp)-1.453152027 +#define A5 (numtyp)1.061405429 + +#define SBBITS 30 +#define NEIGHMASK 0x3FFFFFFF +__inline int sbmask(int j) { return j >> SBBITS & 3; } + +__kernel void kernel_pair(__global numtyp4 *x_, __global numtyp4 *lj1, + __global numtyp4* lj3, const int lj_types, + __global numtyp *sp_cl_in, __global int *dev_nbor, + __global int *dev_packed, __global acctyp4 *ans, + __global acctyp *engv, const int eflag, + const int vflag, const int inum, + const int nbor_pitch, __global numtyp *q_, + const numtyp cut_coulsq, const numtyp qqrd2e, + const numtyp g_ewald, const int t_per_atom) { + int tid=THREAD_ID_X; + int ii=mul24((int)BLOCK_ID_X,(int)(BLOCK_SIZE_X)/t_per_atom); + ii+=tid/t_per_atom; + int offset=tid%t_per_atom; + + __local numtyp sp_cl[4]; + sp_cl[0]=sp_cl_in[0]; + sp_cl[1]=sp_cl_in[1]; + sp_cl[2]=sp_cl_in[2]; + sp_cl[3]=sp_cl_in[3]; + + acctyp e_coul=(acctyp)0; + acctyp4 f; + f.x=(acctyp)0; + f.y=(acctyp)0; + f.z=(acctyp)0; + acctyp virial[6]; + for (int i=0; i<6; i++) + virial[i]=(acctyp)0; + + if (ii0) { + e_coul += prefactor*(_erfc-factor_coul); + } + if (vflag>0) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + + // Reduce answers + if (t_per_atom>1) { + __local acctyp red_acc[6][BLOCK_PAIR]; + + red_acc[0][tid]=f.x; + red_acc[1][tid]=f.y; + red_acc[2][tid]=f.z; + red_acc[3][tid]=e_coul; + + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { + if (offset < s) { + for (int r=0; r<4; r++) + red_acc[r][tid] += red_acc[r][tid+s]; + } + } + + f.x=red_acc[0][tid]; + f.y=red_acc[1][tid]; + f.z=red_acc[2][tid]; + e_coul=red_acc[3][tid]; + + if (vflag>0) { + for (int r=0; r<6; r++) + red_acc[r][tid]=virial[r]; + + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { + if (offset < s) { + for (int r=0; r<6; r++) + red_acc[r][tid] += red_acc[r][tid+s]; + } + } + + for (int r=0; r<6; r++) + virial[r]=red_acc[r][tid]; + } + } + + // Store answers + if (ii0) { + *ap1=(acctyp)0; + ap1+=inum; + *ap1=e_coul; + ap1+=inum; + } + if (vflag>0) { + for (int i=0; i<6; i++) { + *ap1=virial[i]; + ap1+=inum; + } + } + ans[ii]=f; + } // if ii +} + +__kernel void kernel_pair_fast(__global numtyp4 *x_, __global numtyp4 *lj1_in, + __global numtyp4* lj3_in, + __global numtyp* sp_cl_in, + __global int *dev_nbor, __global int *dev_packed, + __global acctyp4 *ans, __global acctyp *engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, __global numtyp *q_, + const numtyp cut_coulsq, const numtyp qqrd2e, + const numtyp g_ewald, const int t_per_atom) { + int tid=THREAD_ID_X; + int ii=mul24((int)BLOCK_ID_X,(int)(BLOCK_SIZE_X)/t_per_atom); + ii+=tid/t_per_atom; + int offset=tid%t_per_atom; + + __local numtyp sp_cl[4]; + if (tid<4) + sp_cl[tid]=sp_cl_in[tid]; + + acctyp e_coul=(acctyp)0; + acctyp4 f; + f.x=(acctyp)0; + f.y=(acctyp)0; + f.z=(acctyp)0; + acctyp virial[6]; + for (int i=0; i<6; i++) + virial[i]=(acctyp)0; + + __syncthreads(); + + if (ii0) { + e_coul += prefactor*(_erfc-factor_coul); + } + if (vflag>0) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + + // Reduce answers + if (t_per_atom>1) { + __local acctyp red_acc[6][BLOCK_PAIR]; + + red_acc[0][tid]=f.x; + red_acc[1][tid]=f.y; + red_acc[2][tid]=f.z; + red_acc[3][tid]=e_coul; + + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { + if (offset < s) { + for (int r=0; r<4; r++) + red_acc[r][tid] += red_acc[r][tid+s]; + } + } + + f.x=red_acc[0][tid]; + f.y=red_acc[1][tid]; + f.z=red_acc[2][tid]; + e_coul=red_acc[3][tid]; + + if (vflag>0) { + for (int r=0; r<6; r++) + red_acc[r][tid]=virial[r]; + + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { + if (offset < s) { + for (int r=0; r<6; r++) + red_acc[r][tid] += red_acc[r][tid+s]; + } + } + + for (int r=0; r<6; r++) + virial[r]=red_acc[r][tid]; + } + } + + // Store answers + if (ii0) { + *ap1=(acctyp)0; + ap1+=inum; + *ap1=e_coul; + ap1+=inum; + } + if (vflag>0) { + for (int i=0; i<6; i++) { + *ap1=virial[i]; + ap1+=inum; + } + } + ans[ii]=f; + } // if ii*/ +} + +#endif + diff --git a/lib/gpu/coul_long_gpu_memory.cpp b/lib/gpu/coul_long_gpu_memory.cpp new file mode 100644 index 0000000000..7ea4077954 --- /dev/null +++ b/lib/gpu/coul_long_gpu_memory.cpp @@ -0,0 +1,158 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Mike Brown (ORNL), brownw@ornl.gov +------------------------------------------------------------------------- */ + +#ifdef USE_OPENCL +#include "coul_long_gpu_cl.h" +#else +#include "coul_long_gpu_ptx.h" +#endif + +#include "coul_long_gpu_memory.h" +#include +#define CL_GPU_MemoryT CL_GPU_Memory + +extern PairGPUDevice pair_gpu_device; + +template +CL_GPU_MemoryT::CL_GPU_Memory() : ChargeGPUMemory(), + _allocated(false) { +} + +template +CL_GPU_MemoryT::~CL_GPU_Memory() { + clear(); +} + +template +int CL_GPU_MemoryT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int CL_GPU_MemoryT::init(const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *_screen, + const double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald) { + int success; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,coul_long_gpu_kernel); + if (success!=0) + return success; + + // we don't have atom types for coulomb only, + // but go with the minimum so that we can use + // the same infrastructure as lj/cut/coul/long/gpu. + int lj_types=1; + shared_types=false; + int max_shared_types=this->device->max_shared_types(); + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_OPTIMIZED); + + for (int i=0; iucl_device),UCL_READ_ONLY); + lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + + sp_cl.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + for (int i=0; i<4; i++) { + host_write[i]=host_special_coul[i]; + } + ucl_copy(sp_cl,host_write,4,false); + + _cut_coulsq=host_cut_coulsq; + _qqrd2e=qqrd2e; + _g_ewald=g_ewald; + + _allocated=true; + this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+sp_cl.row_bytes(); + return 0; +} + +template +void CL_GPU_MemoryT::clear() { + if (!_allocated) + return; + _allocated=false; + + lj1.clear(); + lj3.clear(); + sp_cl.clear(); + this->clear_atomic(); +} + +template +double CL_GPU_MemoryT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(CL_GPU_Memory); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +void CL_GPU_MemoryT::loop(const bool _eflag, const bool _vflag) { + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int eflag, vflag; + if (_eflag) + eflag=1; + else + eflag=0; + + if (_vflag) + vflag=1; + else + vflag=0; + + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_fast.set_size(GX,BX); + this->k_pair_fast.run(&this->atom->dev_x.begin(), &lj1.begin(), + &lj3.begin(), &sp_cl.begin(), + &this->nbor->dev_nbor.begin(), + &this->_nbor_data->begin(), + &this->ans->dev_ans.begin(), + &this->ans->dev_engv.begin(), &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->dev_q.begin(), + &_cut_coulsq, &_qqrd2e, &_g_ewald, + &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->dev_x.begin(), &lj1.begin(), &lj3.begin(), + &_lj_types, &sp_cl.begin(), &this->nbor->dev_nbor.begin(), + &this->_nbor_data->begin(), &this->ans->dev_ans.begin(), + &this->ans->dev_engv.begin(), &eflag, &vflag, &ainum, + &nbor_pitch, &this->atom->dev_q.begin(), &_cut_coulsq, + &_qqrd2e, &_g_ewald, &this->_threads_per_atom); + } + this->time_pair.stop(); +} + +template class CL_GPU_Memory; diff --git a/lib/gpu/coul_long_gpu_memory.h b/lib/gpu/coul_long_gpu_memory.h new file mode 100644 index 0000000000..04914a2514 --- /dev/null +++ b/lib/gpu/coul_long_gpu_memory.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Mike Brown (ORNL), brownw@ornl.gov +------------------------------------------------------------------------- */ + +#ifndef CL_GPU_MEMORY_H +#define CL_GPU_MEMORY_H + +#include "charge_gpu_memory.h" + +template +class CL_GPU_Memory : public ChargeGPUMemory { + public: + CL_GPU_Memory(); + ~CL_GPU_Memory(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successfull + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, + const double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + // --------------------------- TYPE DATA -------------------------- + + /// lj1 dummy + UCL_D_Vec lj1; + /// lj3 dummy + UCL_D_Vec lj3; + /// Special Coul values [0-3] + UCL_D_Vec sp_cl; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + numtyp _cut_coulsq, _qqrd2e, _g_ewald; + + private: + bool _allocated; + void loop(const bool _eflag, const bool _vflag); +}; + +#endif + From e77ec4dea6c9c91fde9e1cb6cdbb63ce83dad07e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:12:28 +0000 Subject: [PATCH 011/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6767 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/GPU/Install.sh | 7 +++++++ src/GPU/Package.sh | 6 ++++++ src/GPU/pair_cg_cmm_coul_long_gpu.cpp | 4 ++-- src/GPU/pair_cg_cmm_coul_msm_gpu.cpp | 2 +- src/GPU/pair_gayberne_gpu.cpp | 6 +++--- src/GPU/pair_lj96_cut_gpu.cpp | 2 +- src/GPU/pair_lj_charmm_coul_long_gpu.cpp | 4 ++-- src/GPU/pair_lj_class2_coul_long_gpu.cpp | 4 ++-- src/GPU/pair_lj_class2_gpu.cpp | 2 +- src/GPU/pair_lj_cut_coul_cut_gpu.cpp | 4 ++-- src/GPU/pair_lj_cut_coul_long_gpu.cpp | 4 ++-- src/GPU/pair_lj_cut_gpu.cpp | 2 +- src/GPU/pair_lj_cut_tgpu.cpp | 2 +- src/GPU/pair_lj_expand_gpu.cpp | 2 +- src/GPU/pair_morse_gpu.cpp | 2 +- src/GPU/pair_resquared_gpu.cpp | 6 +++--- 16 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/GPU/Install.sh b/src/GPU/Install.sh index 32ee689bed..4f16599890 100644 --- a/src/GPU/Install.sh +++ b/src/GPU/Install.sh @@ -45,6 +45,11 @@ if (test $1 = 1) then cp pair_lj_charmm_coul_long_gpu.h .. fi + if (test -e ../pair_coul_long.cpp) then + cp pair_coul_long_gpu.cpp .. + cp pair_coul_long_gpu.h .. + fi + if (test -e ../pair_cg_cmm.cpp) then cp pair_cg_cmm_gpu.cpp .. cp pair_cg_cmm_gpu.h .. @@ -112,6 +117,7 @@ elif (test $1 = 0) then rm -f ../pair_lj_class2_coul_long_gpu.cpp rm -f ../pair_lj_charmm_coul_long_gpu.cpp rm -f ../pair_lj_cut_tgpu.cpp + rm -f ../pair_coul_long_gpu.cpp rm -f ../pair_cg_cmm_gpu.cpp rm -f ../pair_cg_cmm_coul_long_gpu.cpp rm -f ../pair_cg_cmm_coul_msm.cpp @@ -134,6 +140,7 @@ elif (test $1 = 0) then rm -f ../pair_lj_class2_coul_long_gpu.h rm -f ../pair_lj_charmm_coul_long_gpu.h rm -f ../pair_lj_cut_tgpu.h + rm -f ../pair_coul_long_gpu.h rm -f ../pair_cg_cmm_gpu.h rm -f ../pair_cg_cmm_coul_long_gpu.h rm -f ../pair_cg_cmm_coul_msm.h diff --git a/src/GPU/Package.sh b/src/GPU/Package.sh index 60aa6820ca..2eb20755e6 100644 --- a/src/GPU/Package.sh +++ b/src/GPU/Package.sh @@ -15,6 +15,12 @@ for file in *.cpp *.h; do if (test $file = pair_lj_cut_coul_long_gpu.h -a ! -e ../pair_lj_cut_coul_long.cpp) then continue fi + if (test $file = pair_coul_long_gpu.cpp -a ! -e ../pair_coul_long.cpp) then + continue + fi + if (test $file = pair_coul_long_gpu.h -a ! -e ../pair_coul_long.cpp) then + continue + fi if (test $file = pair_cg_cmm_gpu.cpp -a ! -e ../pair_cg_cmm.cpp) then continue fi diff --git a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp index 153cb98a9e..d19b2d6512 100644 --- a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp +++ b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp @@ -144,9 +144,9 @@ void PairCGCMMCoulLongGPU::init_style() cut_respa = NULL; if (!atom->q_flag) - error->all("Pair style cg/cmm/coul/long requires atom attribute q"); + error->all("Pair style cg/cmm/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with GPU cg/cmm pair style"); + error->all("Cannot use newton pair with cg/cmm/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp b/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp index e88144bea1..d946b739d5 100644 --- a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp +++ b/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp @@ -136,7 +136,7 @@ void PairCGCMMCoulMSMGPU::init_style() { PairCGCMMCoulMSM::init_style(); if (force->newton_pair) - error->all("Cannot use newton pair with GPU cg/cmm pair style"); + error->all("Cannot use newton pair with cg/cmm/coul/msm/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_gayberne_gpu.cpp b/src/GPU/pair_gayberne_gpu.cpp index 6713242885..c137f0f67c 100644 --- a/src/GPU/pair_gayberne_gpu.cpp +++ b/src/GPU/pair_gayberne_gpu.cpp @@ -156,9 +156,9 @@ void PairGayBerneGPU::compute(int eflag, int vflag) void PairGayBerneGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with GPU Gay-Berne pair style"); + error->all("Cannot use newton pair with gayberne/gpu pair style"); if (!atom->ellipsoid_flag) - error->all("Pair gayberne requires atom style ellipsoid"); + error->all("Pair gayberne/gpu requires atom style ellipsoid"); // per-type shape precalculations // require that atom shapes are identical within each type @@ -166,7 +166,7 @@ void PairGayBerneGPU::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair gayberne requires atoms with same type have same shape"); + error->all("Pair gayberne/gpu requires atoms with same type have same shape"); if (shape1[i][0] == 0.0) shape1[i][0] = shape1[i][1] = shape1[i][2] = 1.0; shape2[i][0] = shape1[i][0]*shape1[i][0]; diff --git a/src/GPU/pair_lj96_cut_gpu.cpp b/src/GPU/pair_lj96_cut_gpu.cpp index 108b108125..ce51b12a7b 100644 --- a/src/GPU/pair_lj96_cut_gpu.cpp +++ b/src/GPU/pair_lj96_cut_gpu.cpp @@ -128,7 +128,7 @@ void PairLJ96CutGPU::init_style() cut_respa = NULL; if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ96 pair style"); + error->all("Cannot use newton pair with lj96/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp index f66319d66d..fa48db0d9a 100644 --- a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp @@ -147,9 +147,9 @@ void PairLJCharmmCoulLongGPU::init_style() cut_respa = NULL; if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/long requires atom attribute q"); + error->all("Pair style lj/charmm/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with GPU CHARMM pair style"); + error->all("Cannot use newton pair with lj/charmm/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double cut; diff --git a/src/GPU/pair_lj_class2_coul_long_gpu.cpp b/src/GPU/pair_lj_class2_coul_long_gpu.cpp index 6441f05419..2c7ea41531 100644 --- a/src/GPU/pair_lj_class2_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_class2_coul_long_gpu.cpp @@ -142,9 +142,9 @@ void PairLJClass2CoulLongGPU::compute(int eflag, int vflag) void PairLJClass2CoulLongGPU::init_style() { if (!atom->q_flag) - error->all("Pair style lj/class2/coul/long requires atom attribute q"); + error->all("Pair style lj/class2/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/class2/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_class2_gpu.cpp b/src/GPU/pair_lj_class2_gpu.cpp index f351c7ab97..c45fb5bfdb 100644 --- a/src/GPU/pair_lj_class2_gpu.cpp +++ b/src/GPU/pair_lj_class2_gpu.cpp @@ -125,7 +125,7 @@ void PairLJClass2GPU::compute(int eflag, int vflag) void PairLJClass2GPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ96 pair style"); + error->all("Cannot use newton pair with lj/class2/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp index 791e47410e..cd19e81ca2 100644 --- a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp @@ -133,10 +133,10 @@ void PairLJCutCoulCutGPU::compute(int eflag, int vflag) void PairLJCutCoulCutGPU::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut requires atom attribute q"); + error->all("Pair style lj/cut/coul/cut/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/cut/coul/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_coul_long_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_gpu.cpp index ad0414e6bb..2b3a915f0e 100644 --- a/src/GPU/pair_lj_cut_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_long_gpu.cpp @@ -145,9 +145,9 @@ void PairLJCutCoulLongGPU::init_style() cut_respa = NULL; if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut requires atom attribute q"); + error->all("Pair style lj/cut/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/cut/could/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_gpu.cpp b/src/GPU/pair_lj_cut_gpu.cpp index c37ce7bd56..63a908d3e7 100644 --- a/src/GPU/pair_lj_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_gpu.cpp @@ -128,7 +128,7 @@ void PairLJCutGPU::init_style() cut_respa = NULL; if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_tgpu.cpp b/src/GPU/pair_lj_cut_tgpu.cpp index 2807fdaf60..043cf0e5bb 100644 --- a/src/GPU/pair_lj_cut_tgpu.cpp +++ b/src/GPU/pair_lj_cut_tgpu.cpp @@ -140,7 +140,7 @@ void PairLJCutTGPU::init_style() cut_respa = NULL; if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/cut/tgpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_expand_gpu.cpp b/src/GPU/pair_lj_expand_gpu.cpp index fc0c8812a3..f45429a9db 100644 --- a/src/GPU/pair_lj_expand_gpu.cpp +++ b/src/GPU/pair_lj_expand_gpu.cpp @@ -127,7 +127,7 @@ void PairLJExpandGPU::compute(int eflag, int vflag) void PairLJExpandGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with GPU LJ pair style"); + error->all("Cannot use newton pair with lj/expand/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_morse_gpu.cpp b/src/GPU/pair_morse_gpu.cpp index a0d6be917b..ae5fcdfe64 100644 --- a/src/GPU/pair_morse_gpu.cpp +++ b/src/GPU/pair_morse_gpu.cpp @@ -125,7 +125,7 @@ void PairMorseGPU::compute(int eflag, int vflag) void PairMorseGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with GPU Morse pair style"); + error->all("Cannot use newton pair with morse/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_resquared_gpu.cpp b/src/GPU/pair_resquared_gpu.cpp index 3d9a5b9f9a..69b6060394 100644 --- a/src/GPU/pair_resquared_gpu.cpp +++ b/src/GPU/pair_resquared_gpu.cpp @@ -155,9 +155,9 @@ void PairRESquaredGPU::compute(int eflag, int vflag) void PairRESquaredGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with GPU RESquared pair style"); + error->all("Cannot use newton pair with resquared/gpu pair style"); if (!atom->ellipsoid_flag) - error->all("Pair resquared requires atom style ellipsoid"); + error->all("Pair resquared/gpu requires atom style ellipsoid"); // per-type shape precalculations // require that atom shapes are identical within each type @@ -165,7 +165,7 @@ void PairRESquaredGPU::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair gayberne requires atoms with same type have same shape"); + error->all("Pair resquared/gpu requires atoms with same type have same shape"); if (setwell[i]) { shape2[i][0] = shape1[i][0]*shape1[i][0]; shape2[i][1] = shape1[i][1]*shape1[i][1]; From 5414a66be0cd7905aa182233753e0931f561dbff Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:12:41 +0000 Subject: [PATCH 012/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6768 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/GPU/pair_coul_long_gpu.cpp | 282 +++++++++++++++++++++++++++++++++ src/GPU/pair_coul_long_gpu.h | 47 ++++++ 2 files changed, 329 insertions(+) create mode 100644 src/GPU/pair_coul_long_gpu.cpp create mode 100644 src/GPU/pair_coul_long_gpu.h diff --git a/src/GPU/pair_coul_long_gpu.cpp b/src/GPU/pair_coul_long_gpu.cpp new file mode 100644 index 0000000000..468821dcec --- /dev/null +++ b/src/GPU/pair_coul_long_gpu.cpp @@ -0,0 +1,282 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Mike Brown (SNL) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "pair_coul_long_gpu.h" +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "integrate.h" +#include "memory.h" +#include "error.h" +#include "neigh_request.h" +#include "universe.h" +#include "update.h" +#include "domain.h" +#include "string.h" +#include "kspace.h" +#include "gpu_extra.h" + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +// External functions from cuda library for atom decomposition + +int cl_gpu_init(const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, int &gpu_mode, + FILE *screen, double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald); +void cl_gpu_clear(); +int ** cl_gpu_compute_n(const int ago, const int inum, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, int *tag, + int **nspecial, int **special, const bool eflag, + const bool vflag, const bool eatom, const bool vatom, + int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double *host_q, + double *boxlo, double *prd); +void cl_gpu_compute(const int ago, const int inum, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, + const int nlocal, double *boxlo, double *prd); +double cl_gpu_bytes(); + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairCoulLongGPU::PairCoulLongGPU(LAMMPS *lmp) : + PairCoulLong(lmp), gpu_mode(GPU_PAIR) +{ + respa_enable = 0; + cpu_time = 0.0; +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairCoulLongGPU::~PairCoulLongGPU() +{ + cl_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulLongGPU::compute(int eflag, int vflag) +{ + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + if (gpu_mode == GPU_NEIGH) { + inum = atom->nlocal; + firstneigh = cl_gpu_compute_n(neighbor->ago, inum, nall, atom->x, + atom->type, domain->sublo, domain->subhi, + atom->tag, atom->nspecial, atom->special, + eflag, vflag, eflag_atom, vflag_atom, + host_start, &ilist, &numneigh, cpu_time, + success, atom->q, domain->boxlo, + domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + cl_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, + ilist, numneigh, firstneigh, eflag, vflag, eflag_atom, + vflag_atom, host_start, cpu_time, success, atom->q, + atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) + error->one("Out of memory on GPGPU"); + + if (host_startq_flag) + error->all("Pair style coul/long/gpu requires atom attribute q"); + if (force->newton_pair) + error->all("Cannot use newton pair with coul/long/gpu pair style"); + + // Repeat cutsq calculation because done after call to init_style + double cell_size = sqrt(cut_coul) + neighbor->skin; + + cut_coulsq = cut_coul * cut_coul; + + // insure use of KSpace long-range solver, set g_ewald + + if (force->kspace == NULL) + error->all("Pair style is incompatible with KSpace style"); + g_ewald = force->kspace->g_ewald; + + // setup force tables + + if (ncoultablebits) init_tables(); + + int maxspecial=0; + if (atom->molecular) + maxspecial=atom->maxspecial; + int success = cl_gpu_init(atom->nlocal, atom->nlocal+atom->nghost, 300, + maxspecial, cell_size, gpu_mode, screen, cut_coulsq, + force->special_coul, force->qqrd2e, g_ewald); + + GPU_EXTRA::check_flag(success,error,world); + + if (gpu_mode != GPU_NEIGH) { + int irequest = neighbor->request(this); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairCoulLongGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + cl_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulLongGPU::cpu_compute(int start, int inum, int eflag, + int vflag, int *ilist, int *numneigh, + int **firstneigh) +{ + int i,j,ii,jj,jnum,itype,jtype,itable; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double fraction,table; + double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + int *jlist; + double rsq; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + int *type = atom->type; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + + // loop over neighbors of my atoms + + for (ii = start; 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]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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]; + + r2inv = 1.0/rsq; + + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + + fpair = forcecoul * r2inv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + + if (eflag) { + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = qtmp*q[j] * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + } + + if (evflag) ev_tally_full(i,0.0,ecoul,fpair,delx,dely,delz); + } + } + } +} diff --git a/src/GPU/pair_coul_long_gpu.h b/src/GPU/pair_coul_long_gpu.h new file mode 100644 index 0000000000..a84b281447 --- /dev/null +++ b/src/GPU/pair_coul_long_gpu.h @@ -0,0 +1,47 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(coul/long/gpu,PairCoulLongGPU) + +#else + +#ifndef LMP_PAIR_COUL_LONG_GPU_H +#define LMP_PAIR_COUL_LONG_GPU_H + +#include "pair_coul_long.h" + +namespace LAMMPS_NS { + +class PairCoulLongGPU : public PairCoulLong { + public: + PairCoulLongGPU(LAMMPS *lmp); + ~PairCoulLongGPU(); + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int); + void init_style(); + double memory_usage(); + + enum { GPU_PAIR, GPU_NEIGH }; + + private: + int gpu_mode; + double cpu_time; + int *gpulist; +}; + +} +#endif +#endif + From a3c3214428cf26bf2cfe7cfa3b360464119dd526 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 21:12:47 +0000 Subject: [PATCH 013/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6769 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/KSPACE/pair_coul_long.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/KSPACE/pair_coul_long.h b/src/KSPACE/pair_coul_long.h index 2de7fa9d14..59e2c7609d 100644 --- a/src/KSPACE/pair_coul_long.h +++ b/src/KSPACE/pair_coul_long.h @@ -28,19 +28,19 @@ class PairCoulLong : public Pair { public: PairCoulLong(class LAMMPS *); ~PairCoulLong(); - void compute(int, int); - void settings(int, char **); + virtual void compute(int, int); + virtual void settings(int, char **); void coeff(int, char **); - void init_style(); + virtual 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 *); - double single(int, int, int, int, double, double, double, double &); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + virtual double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - private: + protected: double cut_coul,cut_coulsq; double *cut_respa; double g_ewald; From 6ac01bf0d4e08e7361a34f149445b43ef6022258 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 23:10:45 +0000 Subject: [PATCH 014/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6772 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Developers.pdf | Bin 0 -> 86207 bytes doc/Manual.html | 3 +++ doc/Manual.txt | 5 ++++- doc/pair_coul.html | 5 ++--- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 doc/Developers.pdf diff --git a/doc/Developers.pdf b/doc/Developers.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2f45f9b99e0dba14c245815483cf9f3df82430ee GIT binary patch literal 86207 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 PDF file on the WWW site or in the tarball is updated about once per month. This is because it is large, and we don't want it to be part of very patch. + +

  • There is also a Developers.pdf file in the doc directory, which +describes the internal structure and algorithms of LAMMPS.

    LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel Simulator. diff --git a/doc/Manual.txt b/doc/Manual.txt index c8f491b233..d9ba65a19c 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -38,7 +38,10 @@ describe the version you have. :l The "PDF file"_Manual.pdf on the WWW site or in the tarball is updated about once per month. This is because it is large, and we don't want -it to be part of very patch. :ule,l +it to be part of very patch. :l + +There is also a Developers.pdf file in the doc directory, which +describes the internal structure and algorithms of LAMMPS. :ule,l LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel Simulator. diff --git a/doc/pair_coul.html b/doc/pair_coul.html index 2d3b2f623d..c4a8cff731 100644 --- a/doc/pair_coul.html +++ b/doc/pair_coul.html @@ -21,9 +21,8 @@

    pair_style coul/cut cutoff
     pair_style coul/debye kappa cutoff
    -pair_style coul/long cutoff 
    -
    -
    pair_style coul/long/gpu cutoff 
    +pair_style coul/long cutoff
    +pair_style coul/long/gpu cutoff 
     
    • cutoff = global cutoff for Coulombic interactions
    • kappa = Debye length (inverse distance units) From bbf48376e2e45f4256a68920830207b6d88b6dd3 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 23:11:14 +0000 Subject: [PATCH 015/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6773 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Manual.html | 5 +++-- doc/Manual.txt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/Manual.html b/doc/Manual.html index 02d9b1b0c7..bb6be917ce 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -43,8 +43,9 @@ describe the version you have. about once per month. This is because it is large, and we don't want it to be part of very patch. -
    • There is also a Developers.pdf file in the doc directory, which -describes the internal structure and algorithms of LAMMPS. +
    • There is also a Developers.pdf file in the doc +directory, which describes the internal structure and algorithms of +LAMMPS.

    LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel Simulator. diff --git a/doc/Manual.txt b/doc/Manual.txt index d9ba65a19c..f3d15998ce 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -40,8 +40,9 @@ The "PDF file"_Manual.pdf on the WWW site or in the tarball is updated about once per month. This is because it is large, and we don't want it to be part of very patch. :l -There is also a Developers.pdf file in the doc directory, which -describes the internal structure and algorithms of LAMMPS. :ule,l +There is also a "Developers.pdf"_Developers.pdf file in the doc +directory, which describes the internal structure and algorithms of +LAMMPS. :ule,l LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel Simulator. From 97243b694334a03f2355cb58e4dbda909695800a Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 23:21:04 +0000 Subject: [PATCH 016/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6775 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Developers.pdf | Bin 86207 -> 85845 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/Developers.pdf b/doc/Developers.pdf index 2f45f9b99e0dba14c245815483cf9f3df82430ee..9fffa698128e3b25215610d3abe2a3846f3e16b4 100644 GIT binary patch delta 26788 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 C{PzR^ delta 27115 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 From ac4e426f25add8add19db02b11f6ffa51ad575be Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 23:27:13 +0000 Subject: [PATCH 017/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6776 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index c6703557dd..c76581f30c 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "20 Aug 2011" +#define LAMMPS_VERSION "23 Aug 2011" From 9b2cc149095672d8e8cda9eb3edc90af03ef3689 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 23 Aug 2011 23:39:08 +0000 Subject: [PATCH 018/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6778 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Developers.pdf | Bin 85845 -> 85903 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/Developers.pdf b/doc/Developers.pdf index 9fffa698128e3b25215610d3abe2a3846f3e16b4..9bb7302526a3a0936e67e543941669b381914a45 100644 GIT binary patch delta 18289 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 Date: Tue, 23 Aug 2011 23:41:20 +0000 Subject: [PATCH 019/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6779 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Developers.pdf | Bin 85903 -> 85906 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/Developers.pdf b/doc/Developers.pdf index 9bb7302526a3a0936e67e543941669b381914a45..3e09a1100470aacb8130a635698fbfefbd5b5a13 100644 GIT binary patch delta 28295 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

    (`}24W4mD5XN8Oh@1?;&_t<|c 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 a|2c7UuyKG=MU=p0;MfqTs3epm5&jQ!_H7aX From 029a4d2df25702235bc2479186a79ac3953c894f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 24 Aug 2011 14:11:14 +0000 Subject: [PATCH 020/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6780 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/DIPOLE/atom_vec_dipole.cpp | 4 ++-- src/KSPACE/pair_coul_long.h | 14 +++++++------- src/MOLECULE/atom_vec_angle.cpp | 4 ++-- src/MOLECULE/atom_vec_bond.cpp | 4 ++-- src/MOLECULE/atom_vec_full.cpp | 4 ++-- src/MOLECULE/atom_vec_molecular.cpp | 4 ++-- src/PERI/atom_vec_peri.cpp | 4 ++-- src/USER-AWPMD/atom_vec_wavepacket.cpp | 4 ++-- src/USER-EFF/atom_vec_electron.cpp | 4 ++-- src/atom_vec_atomic.cpp | 4 ++-- src/atom_vec_charge.cpp | 4 ++-- src/atom_vec_ellipsoid.cpp | 4 ++-- src/atom_vec_sphere.cpp | 4 ++-- 13 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp index 8d75db578a..cde9b0c806 100644 --- a/src/DIPOLE/atom_vec_dipole.cpp +++ b/src/DIPOLE/atom_vec_dipole.cpp @@ -68,7 +68,7 @@ void AtomVecDipole::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); q = memory->grow(atom->q,nmax,"atom:q"); mu = memory->grow(atom->mu,nmax,4,"atom:mu"); @@ -822,7 +822,7 @@ bigint AtomVecDipole::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("mu")) bytes += memory->usage(mu,nmax,4); diff --git a/src/KSPACE/pair_coul_long.h b/src/KSPACE/pair_coul_long.h index 59e2c7609d..2de7fa9d14 100644 --- a/src/KSPACE/pair_coul_long.h +++ b/src/KSPACE/pair_coul_long.h @@ -28,19 +28,19 @@ class PairCoulLong : public Pair { public: PairCoulLong(class LAMMPS *); ~PairCoulLong(); - virtual void compute(int, int); - virtual void settings(int, char **); + void compute(int, int); + void settings(int, char **); void coeff(int, char **); - virtual void init_style(); + void init_style(); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); - virtual void write_restart_settings(FILE *); - virtual void read_restart_settings(FILE *); - virtual double single(int, int, int, int, double, double, double, double &); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - protected: + private: double cut_coul,cut_coulsq; double *cut_respa; double g_ewald; diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp index ee601d7b81..72afefb8d1 100644 --- a/src/MOLECULE/atom_vec_angle.cpp +++ b/src/MOLECULE/atom_vec_angle.cpp @@ -69,7 +69,7 @@ void AtomVecAngle::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); @@ -816,7 +816,7 @@ bigint AtomVecAngle::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp index 842a28f4b7..fb0a3e0583 100644 --- a/src/MOLECULE/atom_vec_bond.cpp +++ b/src/MOLECULE/atom_vec_bond.cpp @@ -70,7 +70,7 @@ void AtomVecBond::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); @@ -774,7 +774,7 @@ bigint AtomVecBond::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp index 8987986a04..15b3c3a84d 100644 --- a/src/MOLECULE/atom_vec_full.cpp +++ b/src/MOLECULE/atom_vec_full.cpp @@ -70,7 +70,7 @@ void AtomVecFull::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); q = memory->grow(atom->q,nmax,"atom:q"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); @@ -986,7 +986,7 @@ bigint AtomVecFull::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp index f85822722f..75c7df86cb 100644 --- a/src/MOLECULE/atom_vec_molecular.cpp +++ b/src/MOLECULE/atom_vec_molecular.cpp @@ -70,7 +70,7 @@ void AtomVecMolecular::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); @@ -966,7 +966,7 @@ bigint AtomVecMolecular::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp index f42f1d1f4a..95a72d10fd 100644 --- a/src/PERI/atom_vec_peri.cpp +++ b/src/PERI/atom_vec_peri.cpp @@ -72,7 +72,7 @@ void AtomVecPeri::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); vfrac = memory->grow(atom->vfrac,nmax,"atom:vfrac"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); @@ -824,7 +824,7 @@ bigint AtomVecPeri::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("vfrac")) bytes += memory->usage(vfrac,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp index 8af7049746..dd4a0657f8 100644 --- a/src/USER-AWPMD/atom_vec_wavepacket.cpp +++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp @@ -78,7 +78,7 @@ void AtomVecWavepacket::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); q = memory->grow(atom->q,nmax,"atom:q"); spin = memory->grow(atom->spin,nmax,"atom:spin"); @@ -991,7 +991,7 @@ bigint AtomVecWavepacket::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp index 55dd7f5c20..c7affbc384 100644 --- a/src/USER-EFF/atom_vec_electron.cpp +++ b/src/USER-EFF/atom_vec_electron.cpp @@ -72,7 +72,7 @@ void AtomVecElectron::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); q = memory->grow(atom->q,nmax,"atom:q"); spin = memory->grow(atom->spin,nmax,"atom:spin"); @@ -839,7 +839,7 @@ bigint AtomVecElectron::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp index 9f991eb289..a0bf79a127 100644 --- a/src/atom_vec_atomic.cpp +++ b/src/atom_vec_atomic.cpp @@ -64,7 +64,7 @@ void AtomVecAtomic::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) @@ -630,7 +630,7 @@ bigint AtomVecAtomic::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); return bytes; } diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp index 1b9159c33d..5def3bd99f 100644 --- a/src/atom_vec_charge.cpp +++ b/src/atom_vec_charge.cpp @@ -66,7 +66,7 @@ void AtomVecCharge::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); q = memory->grow(atom->q,nmax,"atom:q"); @@ -695,7 +695,7 @@ bigint AtomVecCharge::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("q")) bytes += memory->usage(q,nmax); diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index 80776fedd1..2ccb91a6ca 100755 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -86,7 +86,7 @@ void AtomVecEllipsoid::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); @@ -1246,7 +1246,7 @@ bigint AtomVecEllipsoid::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index 77b33cc816..b17817412e 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -97,7 +97,7 @@ void AtomVecSphere::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3*comm->nthreads,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); radius = memory->grow(atom->radius,nmax,"atom:radius"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); @@ -1048,7 +1048,7 @@ bigint AtomVecSphere::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3*comm->nthreads); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("radius")) bytes += memory->usage(radius,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); From 0cb40558c5fd0202afb0a8f42a2a7fa71334e955 Mon Sep 17 00:00:00 2001 From: athomps Date: Wed, 24 Aug 2011 16:53:00 +0000 Subject: [PATCH 021/246] Added Matt's piston and append code git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6783 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/Install.sh | 8 + src/SHOCK/fix_append_atoms.cpp | 483 +++++++++++++++++++++++++++++++++ src/SHOCK/fix_append_atoms.h | 56 ++++ src/SHOCK/fix_wall_piston.cpp | 325 ++++++++++++++++++++++ src/SHOCK/fix_wall_piston.h | 46 ++++ 5 files changed, 918 insertions(+) create mode 100644 src/SHOCK/fix_append_atoms.cpp create mode 100644 src/SHOCK/fix_append_atoms.h create mode 100644 src/SHOCK/fix_wall_piston.cpp create mode 100644 src/SHOCK/fix_wall_piston.h diff --git a/src/SHOCK/Install.sh b/src/SHOCK/Install.sh index 84f40ddf72..1931770eec 100644 --- a/src/SHOCK/Install.sh +++ b/src/SHOCK/Install.sh @@ -2,18 +2,26 @@ if (test $1 = 1) then + cp fix_append_atoms.cpp .. cp fix_msst.cpp .. cp fix_nphug.cpp .. + cp fix_wall_piston.cpp .. + cp fix_append_atoms.h .. cp fix_msst.h .. cp fix_nphug.h .. + cp fix_wall_piston.h .. elif (test $1 = 0) then + rm -f ../fix_append_atoms.cpp rm -f ../fix_msst.cpp rm -f ../fix_nphug.cpp + rm -f ../fix_wall_piston.cpp + rm -f ../fix_append_atoms.h rm -f ../fix_msst.h rm -f ../fix_nphug.h + rm -f ../fix_wall_piston.h fi diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp new file mode 100644 index 0000000000..0bb38b48a6 --- /dev/null +++ b/src/SHOCK/fix_append_atoms.cpp @@ -0,0 +1,483 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "stdlib.h" +#include "fix_append_atoms.h" +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "modify.h" +#include "domain.h" +#include "lattice.h" +#include "update.h" +#include "random_mars.h" +#include "error.h" +#include "force.h" + +using namespace LAMMPS_NS; + +#define BIG 1.0e30 +#define EPSILON 1.0e-6 + +/* ---------------------------------------------------------------------- */ + +FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + force_reneighbor = 1; + next_reneighbor = -1; + box_change = 1; + time_depend = 1; + + if (narg < 4) error->all("Illegal fix append_atoms command"); + + scaleflag = 1; + spatflag=0; + xloflag = xhiflag = yloflag = yhiflag = zloflag = zhiflag = 0; + + tempflag = 0; + + ranflag = 0; + ranx = 0.0; + rany = 0.0; + ranz = 0.0; + + randomx = NULL; + randomt = NULL; + + int iarg = 0; + iarg = 3; + while (iarg < narg) { + if (strcmp(arg[iarg],"xlo") == 0) { + error->all("Only zhi currently implemented for append_atoms"); + xloflag = 1; + iarg++; + if (domain->boundary[0][0] != 3) error->all("Must shrink-wrap with minimum the append boundary"); + } else if (strcmp(arg[iarg],"xhi") == 0) { + error->all("Only zhi currently implemented for append_atom"); + xhiflag = 1; + iarg++; + if (domain->boundary[0][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + } else if (strcmp(arg[iarg],"ylo") == 0) { + error->all("Only zhi currently implemented for append_atom"); + yloflag = 1; + iarg++; + if (domain->boundary[1][0] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + } else if (strcmp(arg[iarg],"yhi") == 0) { + error->all("Only zhi currently implemented for append_atom"); + yhiflag = 1; + iarg++; + if (domain->boundary[1][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + } else if (strcmp(arg[iarg],"zlo") == 0) { + error->all("Only zhi currently implemented for append_atom"); + zloflag = 1; + iarg++; + if (domain->boundary[2][0] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + } else if (strcmp(arg[iarg],"zhi") == 0) { + zhiflag = 1; + iarg++; + if (domain->boundary[2][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + } else if (strcmp(arg[iarg],"freq") == 0) { + if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + freq = atof(arg[iarg+1]); + iarg += 2; + } else if (strcmp(arg[iarg],"spatial") == 0) { + if (iarg+3 > narg) error->all("Illegal fix append_atoms command"); + if (strcmp(arg[iarg+1],"f_") == 0) error->all("Bad fix ID in fix append_atoms command"); + spatflag = 1; + int n = strlen(arg[iarg+1]); + spatlead = atof(arg[iarg+2]); + char *suffix = new char[n]; + strcpy(suffix,&arg[iarg+1][2]); + n = strlen(suffix) + 1; + spatialid = new char[n]; + strcpy(spatialid,suffix); + delete [] suffix; + iarg += 3; + // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL + } else if (strcmp(arg[iarg],"size") == 0) { + if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + size = atof(arg[iarg+1]); + iarg += 2; + } else if (strcmp(arg[iarg],"units") == 0) { + if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; + else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; + else error->all("Illegal fix append_atoms command"); + iarg += 2; + } else if (strcmp(arg[iarg],"random") == 0) { + if (iarg+5 > narg) error->all("Illegal fix append_atoms command"); + ranflag = 1; + ranx = atof(arg[iarg+1]); + rany = atof(arg[iarg+2]); + ranz = atof(arg[iarg+3]); + xseed = atoi(arg[iarg+4]); + if (xseed <= 0) error->all("Illegal fix append_atoms command"); + randomx = new RanMars(lmp,xseed + comm->me); + iarg += 5; + } else if (strcmp(arg[iarg],"temp") == 0) { + if (iarg+5 > narg) error->all("Illegal fix append_atoms command"); + tempflag = 1; + t_target = atof(arg[iarg+1]); + t_period = atof(arg[iarg+2]); + tseed = atoi(arg[iarg+3]); + t_extent = atof(arg[iarg+4]); + if (t_target <= 0) error->all("Illegal fix append_atoms command"); + if (t_period <= 0) error->all("Illegal fix append_atoms command"); + if (t_extent <= 0) error->all("Illegal fix append_atoms command"); + if (tseed <= 0) error->all("Illegal fix append_atoms command"); + randomt = new RanMars(lmp,tseed + comm->me); + gfactor1 = new double[atom->ntypes+1]; + gfactor2 = new double[atom->ntypes+1]; + iarg += 5; + } else error->all("Illegal fix append_atoms command"); + } + + if ((xloflag || xhiflag) && domain->xperiodic) + error->all("Cannot use append_atoms in periodic dimension"); + if ((yloflag || yhiflag) && domain->yperiodic) + error->all("Cannot use append_atoms in periodic dimension"); + if ((zloflag || zhiflag) && domain->zperiodic) + error->all("Cannot use append_atoms in periodic dimension"); + + if (domain->triclinic == 1) error->all("Cannot append atoms to a triclinic box"); + + // setup scaling + + if (scaleflag && domain->lattice == NULL) + error->all("Use of fix append_atoms with undefined lattice"); + + double xscale,yscale,zscale; + if (scaleflag) { + xscale = domain->lattice->xlattice; + yscale = domain->lattice->ylattice; + zscale = domain->lattice->zlattice; + } + else xscale = yscale = zscale = 1.0; + + if (xloflag || xhiflag) size *= xscale; + if (yloflag || yhiflag) size *= yscale; + if (zloflag || zhiflag) size *= zscale; + + if (ranflag) { + ranx *= xscale; + rany *= yscale; + ranz *= zscale; + } +} + +/* ---------------------------------------------------------------------- */ + +FixAppendAtoms::~FixAppendAtoms() +{ + if (ranflag) delete randomx; + if (tempflag) { + delete randomt; + delete [] gfactor1; + delete [] gfactor2; + } +} + +/* ---------------------------------------------------------------------- */ + +int FixAppendAtoms::setmask() +{ + int mask = 0; + mask |= PRE_EXCHANGE; + mask |= INITIAL_INTEGRATE; + mask |= POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixAppendAtoms::initial_integrate(int vflag) +{ + if (update->ntimestep % freq == 0) { + next_reneighbor = update->ntimestep; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixAppendAtoms::setup(int vflag) +{ + /*** CALL TO CREATE GROUP? SEE POST_FORCE ***/ + post_force(vflag); +} + + +/* ---------------------------------------------------------------------- */ + +int FixAppendAtoms::get_spatial() +{ + if (update->ntimestep % freq == 0) { + int ifix = modify->find_fix(spatialid); + if (ifix < 0) + error->all("Fix ID for fix ave/spatial does not exist"); + Fix *fix = modify->fix[ifix]; + + int failed = 0; + int count = 0; + while (failed < 2) { + double tmp = fix->compute_vector(2*count); + if (tmp == 0.0) failed++; + else failed = 0; + count++; + } + double pos[count-2]; + double val[count-2]; + for (int loop=0; loop < count-2; loop++) { + pos[loop] = fix->compute_vector(2*loop); + val[loop] = fix->compute_vector(2*loop+1); + } + +// Always ignor the first and last +// SHOULD HAVE A MEMORY OF MIN AND MAX ENERGY +// CAPTURE BINSIZE FROM SPATIAL + + double binsize = 2.0; + double min_energy=0.0; + double max_energy=0.0; + int header = size / binsize; + advance = 0; + + for (int loop=1; loop <= header; loop++) { + max_energy += val[loop]; + } + for (int loop=count-2-2*header; loop <=count-3-header; loop++) { + min_energy += val[loop]; + } + max_energy /= header; + min_energy /= header; + + double shockfront_min = 0.0; + double shockfront_max = 0.0; + double shockfront_loc = 0.0; + int front_found1 = 0; + for (int loop=count-3-header; loop > header; loop--) { + if (front_found1 == 1) continue; + if (val[loop] > min_energy + 0.1*(max_energy - min_energy)) { + shockfront_max = pos[loop]; + front_found1=1; + } + } + int front_found2 = 0; + for (int loop=header+1; loop <=count-3-header; loop++) { + if (val[loop] > min_energy + 0.6*(max_energy - min_energy)) { + shockfront_min = pos[loop]; + front_found2=1; + } + } + if (front_found1 + front_found2 == 0) shockfront_loc = 0.0; + else if (front_found1 + front_found2 == 1) shockfront_loc = shockfront_max + shockfront_min; + else if (front_found1 == 1 && front_found2 == 1 && shockfront_max-shockfront_min > spatlead/2.0) shockfront_loc = shockfront_max; + else shockfront_loc = (shockfront_max + shockfront_min) / 2.0; + if (comm->me == 0) printf("SHOCK: %g %g %g %g %g\n", shockfront_loc, shockfront_min, shockfront_max, domain->boxlo[2], domain->boxhi[2]); + + if (domain->boxhi[2] - shockfront_loc < spatlead) advance = 1; + } + + advance_sum = 0; + MPI_Allreduce(&advance,&advance_sum,1,MPI_INT,MPI_SUM,world); + + if (advance_sum > 0) return 1; + else return 0; +} + +/* ---------------------------------------------------------------------- */ + +void FixAppendAtoms::post_force(int vflag) +{ + double **f = atom->f; + double **v = atom->v; + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + + double gamma1,gamma2; + double tsqrt = sqrt(t_target); + + if (atom->mass) { + if (tempflag) { + for (int i = 1; i <= atom->ntypes; i++) { + gfactor1[i] = -atom->mass[i] / t_period / force->ftm2v; + gfactor2[i] = sqrt(atom->mass[i]) * + sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) / + force->ftm2v; + } + } + for (int i = 0; i < nlocal; i++) { + // SET TEMP AHEAD OF SHOCK + if (tempflag && x[i][2] >= domain->boxhi[2] - t_extent ) { + gamma1 = gfactor1[type[i]]; + gamma2 = gfactor2[type[i]] * tsqrt; + f[i][0] += gamma1*v[i][0] + gamma2*(randomt->uniform()-0.5); + f[i][1] += gamma1*v[i][1] + gamma2*(randomt->uniform()-0.5); + f[i][2] += gamma1*v[i][2] + gamma2*(randomt->uniform()-0.5); + } + // FREEZE ATOMS AT BOUNDARY + if (x[i][2] >= domain->boxhi[2] - size) { + f[i][0] = 0.0; + f[i][1] = 0.0; + f[i][2] = 0.0; + v[i][0] = 0.0; + v[i][1] = 0.0; + v[i][2] = 0.0; + } + } + } else { + double *rmass = atom->rmass; + double boltz = force->boltz; + double dt = update->dt; + double mvv2e = force->mvv2e; + double ftm2v = force->ftm2v; + + for (int i = 0; i < nlocal; i++) { + // SET TEMP AHEAD OF SHOCK + if (tempflag && x[i][2] >= domain->boxhi[2] - t_extent ) { + gamma1 = -rmass[i] / t_period / ftm2v; + gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v; + gamma2 *= tsqrt; + f[i][0] += gamma1*v[i][0] + gamma2*(randomt->uniform()-0.5); + f[i][1] += gamma1*v[i][1] + gamma2*(randomt->uniform()-0.5); + f[i][2] += gamma1*v[i][2] + gamma2*(randomt->uniform()-0.5); + } + // FREEZE ATOMS AT BOUNDARY + if (x[i][2] >= domain->boxhi[2] - size) { + f[i][0] = 0.0; + f[i][1] = 0.0; + f[i][2] = 0.0; + v[i][0] = 0.0; + v[i][1] = 0.0; + v[i][2] = 0.0; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixAppendAtoms::pre_exchange() +{ + int ntimestep = update->ntimestep; + int addnode = 0; + + if (ntimestep % freq == 0) { + if (spatflag==1) if (get_spatial()==0) return; + if (comm->myloc[2] == comm->procgrid[2]-1) { + if (domain->lattice) { + nbasis = domain->lattice->nbasis; + basistype = new int[nbasis]; + for (int i = 0; i < nbasis; i++) basistype[i] = 1; + } else error->all("must define lattice to append_atoms"); + + double bboxlo[3],bboxhi[3]; + + bboxlo[0] = domain->sublo[0]; bboxhi[0] = domain->subhi[0]; + bboxlo[1] = domain->sublo[1]; bboxhi[1] = domain->subhi[1]; + bboxlo[2] = domain->subhi[2]; bboxhi[2] = domain->subhi[2]+size; + + double xmin,ymin,zmin,xmax,ymax,zmax; + xmin = ymin = zmin = BIG; + xmax = ymax = zmax = -BIG; + + domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxlo[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxlo[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxlo[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxlo[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxhi[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxhi[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxhi[2], + xmin,ymin,zmin,xmax,ymax,zmax); + domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxhi[2], + xmin,ymin,zmin,xmax,ymax,zmax); + + int ilo,ihi,jlo,jhi,klo,khi; + ilo = static_cast (xmin); + jlo = static_cast (ymin); + klo = static_cast (zmin); + ihi = static_cast (xmax); + jhi = static_cast (ymax); + khi = static_cast (zmax); + + if (xmin < 0.0) ilo--; + if (ymin < 0.0) jlo--; + if (zmin < 0.0) klo--; + + double **basis = domain->lattice->basis; + double x[3]; + double *sublo = domain->sublo; + double *subhi = domain->subhi; + double *mass = atom->mass; + + int i,j,k,m; + for (k = klo; k <= khi; k++) { + for (j = jlo; j <= jhi; j++) { + for (i = ilo; i <= ihi; i++) { + for (m = 0; m < nbasis; m++) { + x[0] = i + basis[m][0]; + x[1] = j + basis[m][1]; + x[2] = k + basis[m][2]; + + int flag = 0; + // convert from lattice coords to box coords + domain->lattice->lattice2box(x[0],x[1],x[2]); + + if (x[0] >= sublo[0] && x[0] < subhi[0] && + x[1] >= sublo[1] && x[1] < subhi[1] && + x[2] >= subhi[2] && x[2] < subhi[2]+size) flag = 1; + else if (domain->dimension == 2 && x[1] >= domain->boxhi[1] && + comm->myloc[1] == comm->procgrid[1]-1 && + x[0] >= sublo[0] && x[0] < subhi[0]) flag = 1; + + if (flag) { + if (ranflag) { + x[0] += ranx * 2.0*(randomx->uniform()-0.5); + x[1] += rany * 2.0*(randomx->uniform()-0.5); + x[2] += ranz * 2.0*(randomx->uniform()-0.5); + } + addnode++; + atom->avec->create_atom(basistype[m],x); + } + } + } + } + } + } + int addtotal = 0; + MPI_Barrier(world); + MPI_Allreduce(&addnode,&addtotal,1,MPI_INT,MPI_SUM,world); + + if (addtotal) { + domain->reset_box(); + if (atom->tag_enable) { + atom->tag_extend(); + atom->natoms += addtotal; + if (atom->map_style) { + atom->nghost = 0; + atom->map_init(); + atom->map_set(); + } + } + } + } +} diff --git a/src/SHOCK/fix_append_atoms.h b/src/SHOCK/fix_append_atoms.h new file mode 100644 index 0000000000..3d101b9212 --- /dev/null +++ b/src/SHOCK/fix_append_atoms.h @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(append_atoms,FixAppendAtoms) + +#else + +#ifndef FIX_APPEND_ATOMS_H +#define FIX_APPEND_ATOMS_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixAppendAtoms : public Fix { + public: + FixAppendAtoms(class LAMMPS *, int, char **); + ~FixAppendAtoms(); + int setmask(); + void setup(int); + void pre_exchange(); + void initial_integrate(int); + void post_force(int); + + private: + int get_spatial(); + int spatflag, xloflag, xhiflag, yloflag, yhiflag, zloflag, zhiflag; + int ranflag, tempflag, xseed, tseed; + double ranx, rany, ranz, t_target, t_period, t_extent; + class RanMars *randomx; + class RanMars *randomt; + int scaleflag, freq; + int *basistype, nbasis; + int advance, advance_sum; + double size, spatlead; + char *spatialid; + double tfactor; + double *gfactor1,*gfactor2; +}; + +} + +#endif +#endif diff --git a/src/SHOCK/fix_wall_piston.cpp b/src/SHOCK/fix_wall_piston.cpp new file mode 100644 index 0000000000..9dd6325bb4 --- /dev/null +++ b/src/SHOCK/fix_wall_piston.cpp @@ -0,0 +1,325 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "stdlib.h" +#include "fix_wall_piston.h" +#include "atom.h" +#include "modify.h" +#include "domain.h" +#include "lattice.h" +#include "update.h" +#include "error.h" +#include "random_mars.h" +#include "force.h" +#include "comm.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixWallPiston::FixWallPiston(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + force_reneighbor = 1; + next_reneighbor = -1; + box_change = 1; + time_depend = 1; + + if (narg < 4) error->all("Illegal fix wall/piston command"); + + randomt = NULL; + tempflag = 0; + scaleflag = 1; + roughflag = 0; + rampflag = 0; + rampNL1flag = 0; + rampNL2flag = 0; + rampNL3flag = 0; + rampNL4flag = 0; + rampNL5flag = 0; + x0 = y0 = z0 = vx = vy = vz = 0.0; + xloflag = xhiflag = yloflag = yhiflag = zloflag = zhiflag = 0; + int iarg = 0; + iarg = 3; + while (iarg < narg) { + if (strcmp(arg[iarg],"xlo") == 0) { error->all("Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"ylo") == 0) { error->all("Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"zlo") == 0) { + zloflag = 1; + iarg++; + if (domain->boundary[2][0] != 2) error->all("Must shrink-wrap piston boundary"); + } else if (strcmp(arg[iarg],"xhi") == 0) { error->all("Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"yhi") == 0) { error->all("Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"zhi") == 0) { error->all("Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"vel") == 0) { + if (iarg+4 > narg) error->all("Illegal fix wall/piston command"); + vx = atof(arg[iarg+1]); + vy = atof(arg[iarg+2]); + vz = atof(arg[iarg+3]); + iarg += 4; + } else if (strcmp(arg[iarg],"pos") == 0) { + if (iarg+4 > narg) error->all("Illegal fix wall/piston command"); + x0 = atof(arg[iarg+1]); + y0 = atof(arg[iarg+2]); + z0 = atof(arg[iarg+3]); + iarg += 4; + } else if (strcmp(arg[iarg],"temp") == 0) { + if (iarg+5 > narg) error->all("Illegal fix wall/pistons command"); + tempflag = 1; + t_target = atof(arg[iarg+1]); + t_period = atof(arg[iarg+2]); + tseed = atoi(arg[iarg+3]); + t_extent = atof(arg[iarg+4]); + if (t_target <= 0) error->all("Illegal fix wall/piston command"); + if (t_period <= 0) error->all("Illegal fix wall/piston command"); + if (t_extent <= 0) error->all("Illegal fix wall/piston command"); + if (tseed <= 0) error->all("Illegal fix wall/pistons command"); + randomt = new RanMars(lmp,tseed + comm->me); + gfactor1 = new double[atom->ntypes+1]; + gfactor2 = new double[atom->ntypes+1]; + iarg += 5; + } else if (strcmp(arg[iarg],"rough") == 0) { + roughflag = 1; + roughdist = atof(arg[iarg+1]); + iarg += 2; + } else if (strcmp(arg[iarg],"ramp") == 0) { + rampflag = 1; + iarg++; + } else if (strcmp(arg[iarg],"rampNL1") == 0) { + rampNL1flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"rampNL2") == 0) { + rampNL2flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"rampNL3") == 0) { + rampNL3flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"rampNL4") == 0) { + rampNL4flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"rampNL5") == 0) { + rampNL5flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"units") == 0) { + if (iarg+2 > narg) error->all("Illegal fix wall/piston command"); + if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; + else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; + else error->all("Illegal fix wall/piston command"); + iarg += 2; + } else error->all("Illegal fix wall/piston command"); + } + + if (vx < 0.0 || vy < 0.0 || vz < 0.0) error->all("Illegal fix wall/piston velocity"); + if ((xloflag || xhiflag) && domain->xperiodic) + error->all("Cannot use wall in periodic dimension"); + if ((yloflag || yhiflag) && domain->yperiodic) + error->all("Cannot use wall in periodic dimension"); + if ((zloflag || zhiflag) && domain->zperiodic) + error->all("Cannot use wall in periodic dimension"); + + // setup scaling + + if (scaleflag && domain->lattice == NULL) + error->all("Use of fix wall/piston with undefined lattice"); + + double xscale,yscale,zscale; + if (scaleflag) { + xscale = domain->lattice->xlattice; + yscale = domain->lattice->ylattice; + zscale = domain->lattice->zlattice; + } + else xscale = yscale = zscale = 1.0; + + vx *= xscale; + vy *= yscale; + vz *= zscale; + x0 *= xscale; + y0 *= yscale; + z0 *= zscale; + roughdist *= zscale; + + if (rampflag || rampNL1flag || rampNL2flag || rampNL3flag || rampNL4flag || rampNL5flag) { + maxvx = vx; + maxvy = vy; + maxvz = vz; + } +} + +/* ---------------------------------------------------------------------- */ + +int FixWallPiston::setmask() +{ + int mask = 0; + mask |= POST_INTEGRATE; + mask |= POST_INTEGRATE_RESPA; + mask |= INITIAL_INTEGRATE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixWallPiston::initial_integrate(int vflag) +{ + next_reneighbor = update->ntimestep; +} + +/* ---------------------------------------------------------------------- */ + +void FixWallPiston::post_integrate() +{ + double xlo, xhi, ylo, yhi, zlo, zhi; + + double **x = atom->x; + double **v = atom->v; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double t = (update->ntimestep - update->beginstep) * update->dt; + double tott = (update->endstep - update->beginstep) * update->dt; + double tt = t * t; + double ttt = tt * t; + double tttt = tt * tt; + double t0p5 = sqrt(t/tott); + double t1p5 = t0p5*t0p5*t0p5; + double t2p5 = t1p5*t0p5*t0p5; + + if (rampflag) { + paccelx = maxvx / tott; + paccely = maxvy / tott; + paccelz = maxvz / tott; + + if (zloflag) { zlo = z0 + 0.5 * paccelz * tt; vz = paccelz * t; } + } + else if (rampNL1flag) { + paccelz = maxvz / tott; + angfreq = 6.283185 / (0.5 * tott); + + if (zloflag) { + zlo = z0 + paccelz * (0.5*tt + 1.0/(angfreq*angfreq) - 1.0/(angfreq*angfreq)*cos(angfreq*t)); + vz = paccelz * (t + 1.0/angfreq*sin(angfreq*t)); + } + else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + } + else if (rampNL2flag) { + paccelz = maxvz / tott; + angfreq = 18.84956 / tott; + + if (zloflag) { + zlo = z0 + paccelz * (0.5*tt + 4.0/(3.0*angfreq*angfreq)*(1.0-cos(angfreq*t)) + 1.0/(6.0*angfreq*angfreq)*(1.0-cos(2.0*angfreq*t))); + vz = paccelz * (t + 4.0/(3.0*angfreq)*sin(angfreq*t) + 1.0/(3.0*angfreq)*sin(2.0*angfreq*t)); + } + else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + } + else if (rampNL3flag) { + paccelz = maxvz / tott; + + if (zloflag) { + zlo = z0 + paccelz*tott*tott/2.5 * (t2p5 ); + vz = paccelz * tott * (t1p5 ); + } + else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + } + else if (rampNL4flag) { + paccelz = maxvz / tott; + + if (zloflag) { + zlo = z0 + paccelz/tott/3.0 * (ttt); + vz = paccelz / tott * (tt); + } + else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + } + else if (rampNL5flag) { + paccelz = maxvz / tott; + + if (zloflag) { + zlo = z0 + paccelz/tott/tott/4.0 * (tttt); + vz = paccelz / tott / tott * (ttt); + } + else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + } + else { + if (zloflag) { zlo = z0 + vz * t; } + } + + if (update->ntimestep % 1000 == 0) + if (comm->me == 0) { + if (screen) + fprintf(screen,"SHOCK: step %d t %g zpos %g vz %g az %g zlo %g\n", + update->ntimestep, t, zlo, vz, paccelz, domain->boxlo[2]); + if (logfile) + fprintf(logfile,"SHOCK: step %d t %g zpos %g vz %g az %g zlo %g\n", + update->ntimestep, t, zlo, vz, paccelz, domain->boxlo[2]); + } + + // VIRIAL PRESSURE CONTRIBUTION? + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + roughoff = 0.0; + if (roughflag) { + roughoff += roughdist*fabs((x[i][0] - domain->boxlo[0])/(domain->boxhi[0]-domain->boxlo[0])-0.5); + roughoff += roughdist*fabs((x[i][1] - domain->boxlo[1])/(domain->boxhi[1]-domain->boxlo[1])-0.5); + } + if (zloflag && x[i][2] < zlo - roughoff) { + x[i][2] = 2.0 * (zlo - roughoff) - x[i][2]; + v[i][2] = 2.0 * vz - v[i][2]; + } + } + } + double **f = atom->f; + int *type = atom->type; + + double gamma1,gamma2; + double tsqrt = sqrt(t_target); + + if (atom->mass) { + if (tempflag) { + for (int i = 1; i <= atom->ntypes; i++) { + gfactor1[i] = -atom->mass[i] / t_period / force->ftm2v; + gfactor2[i] = sqrt(atom->mass[i]) * + sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) / + force->ftm2v; + } + } + for (int i = 0; i < nlocal; i++) { + // SET TEMP AHEAD OF PISTON + if (tempflag && x[i][2] <= domain->boxlo[2] + t_extent ) { + gamma1 = gfactor1[type[i]]; + gamma2 = gfactor2[type[i]] * tsqrt; + f[i][0] += gamma1*v[i][0] + gamma2*(randomt->uniform()-0.5); + f[i][1] += gamma1*v[i][1] + gamma2*(randomt->uniform()-0.5); + f[i][2] += gamma1*(v[i][2]-vz) + gamma2*(randomt->uniform()-0.5); + } + } + } else { + double *rmass = atom->rmass; + double boltz = force->boltz; + double dt = update->dt; + double mvv2e = force->mvv2e; + double ftm2v = force->ftm2v; + + for (int i = 0; i < nlocal; i++) { + // SET TEMP AHEAD OF PISTON + if (tempflag && x[i][2] <= domain->boxlo[2] + t_extent ) { + gamma1 = -rmass[i] / t_period / ftm2v; + gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v; + gamma2 *= tsqrt; + f[i][0] += gamma1*v[i][0] + gamma2*(randomt->uniform()-0.5); + f[i][1] += gamma1*v[i][1] + gamma2*(randomt->uniform()-0.5); + f[i][2] += gamma1*v[i][2] + gamma2*(randomt->uniform()-0.5); + } + } + } + +} diff --git a/src/SHOCK/fix_wall_piston.h b/src/SHOCK/fix_wall_piston.h new file mode 100644 index 0000000000..46d4cdee68 --- /dev/null +++ b/src/SHOCK/fix_wall_piston.h @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ +#ifdef FIX_CLASS + +FixStyle(wall/piston,FixWallPiston) + +#else + +#ifndef LMP_FIX_WALL_PISTON_H +#define LMP_FIX_WALL_PISTON_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixWallPiston : public Fix { + public: + FixWallPiston(class LAMMPS *, int, char **); + int setmask(); + void post_integrate(); + void initial_integrate(int); + + private: + int xloflag,xhiflag,yloflag,yhiflag,zloflag,zhiflag; + int scaleflag, roughflag, rampflag, rampNL1flag, rampNL2flag, rampNL3flag, rampNL4flag, rampNL5flag; + double roughdist,roughoff,x0,y0,z0,vx,vy,vz,maxvx,maxvy,maxvz,paccelx,paccely,paccelz, angfreq; + int tempflag, tseed; + double t_target, t_period, t_extent; + class RanMars *randomt; + double *gfactor1,*gfactor2; +}; + +} + +#endif +#endif From 7ea8d72b4fc121995ab9c5b6e316cedd5509cea0 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 14:13:49 +0000 Subject: [PATCH 022/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6785 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_qeq_reax.html | 5 +++++ doc/fix_qeq_reax.txt | 5 +++++ doc/pair_reax_c.html | 7 ++++++- doc/pair_reax_c.txt | 7 ++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/fix_qeq_reax.html b/doc/fix_qeq_reax.html index c241e30a0b..d77df36824 100644 --- a/doc/fix_qeq_reax.html +++ b/doc/fix_qeq_reax.html @@ -37,6 +37,8 @@ reax/c command, but it can be used with any potential in LAMMPS, so long as it defines and uses charges on each atom. The fix qeq/comb command should be used to perform charge equliibration with the COMB potential. +For more technical details about the charge equilibration performed by +fix qeq/reax, see the "(Aktulga)" paper.

    The QEq method minimizes the electrostatic energy of the system by adjusting the partial charge on individual atoms based on interactions @@ -92,4 +94,7 @@ LAMMPS section for more info.

    (Nakano) Nakano, Computer Physics Communications, 104, 59-69 (1997).

    +

    :link(Aktulga) (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel +Computing, to appear (2011). +

    diff --git a/doc/fix_qeq_reax.txt b/doc/fix_qeq_reax.txt index 6c6b95b1c2..228c4da432 100644 --- a/doc/fix_qeq_reax.txt +++ b/doc/fix_qeq_reax.txt @@ -34,6 +34,8 @@ reax/c"_pair_reax_c.html command, but it can be used with any potential in LAMMPS, so long as it defines and uses charges on each atom. The "fix qeq/comb"_fix_qeq_comb.html command should be used to perform charge equliibration with the "COMB potential"_pair_comb.html. +For more technical details about the charge equilibration performed by +fix qeq/reax, see the "(Aktulga)" paper. The QEq method minimizes the electrostatic energy of the system by adjusting the partial charge on individual atoms based on interactions @@ -86,3 +88,6 @@ LAMMPS"_Section_start.html#2_3 section for more info. :link(Nakano_1997) [(Nakano)] Nakano, Computer Physics Communications, 104, 59-69 (1997). + +:link(Aktulga) [(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel +Computing, to appear (2011). diff --git a/doc/pair_reax_c.html b/doc/pair_reax_c.html index 8d4fabb386..6767a7c75a 100644 --- a/doc/pair_reax_c.html +++ b/doc/pair_reax_c.html @@ -38,7 +38,9 @@ energy. There is more than one version of ReaxFF. The version implemented in LAMMPS uses the functional forms documented in the supplemental information of the following paper: (Chenoweth et al., 2008). The version integrated into LAMMPS matches -the most up-to-date version of ReaxFF as of summer 2010. +the most up-to-date version of ReaxFF as of summer 2010. For more +technical details about the pair reax/c implementation of ReaxFF, see +the "(Aktulga)" paper.

    The reax/c style differs from the pair_style reax command in the lo-level implementation details. The reax style is a @@ -272,4 +274,7 @@ will be 0.0.

    (Chenoweth_2008) Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008).

    +

    :link(Aktulga) (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel +Computing, to appear (2011). +

    diff --git a/doc/pair_reax_c.txt b/doc/pair_reax_c.txt index 4fde669ed8..4529260705 100644 --- a/doc/pair_reax_c.txt +++ b/doc/pair_reax_c.txt @@ -34,7 +34,9 @@ energy. There is more than one version of ReaxFF. The version implemented in LAMMPS uses the functional forms documented in the supplemental information of the following paper: "(Chenoweth et al., 2008)"_#Chenoweth_2008. The version integrated into LAMMPS matches -the most up-to-date version of ReaxFF as of summer 2010. +the most up-to-date version of ReaxFF as of summer 2010. For more +technical details about the pair reax/c implementation of ReaxFF, see +the "(Aktulga)" paper. The {reax/c} style differs from the "pair_style reax"_pair_reax.html command in the lo-level implementation details. The {reax} style is a @@ -266,3 +268,6 @@ The keyword default is checkqeq = yes. :link(Chenoweth_2008) [(Chenoweth_2008)] Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008). + +:link(Aktulga) [(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel +Computing, to appear (2011). From 786bcba0818006ef2790badecf197de097126b58 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 14:15:01 +0000 Subject: [PATCH 023/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6786 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-REAXC/README | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/USER-REAXC/README b/src/USER-REAXC/README index d7f66d1a74..9d1c8b1ac7 100644 --- a/src/USER-REAXC/README +++ b/src/USER-REAXC/README @@ -5,6 +5,13 @@ at cs.purdue.edu, while at Purdue University. Contact him directly, or Aidan Thompson (Sandia) at athomps at sandia.gov, if you have questions. +For technical details about this implemention of ReaxFF, see +this paper: + +Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods +and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty, +S. A. Pandit, A. Y. Grama, Parallel Computing, to appear (2011). + -------------------------------------- Note that the files with names starting with "reaxc" in this package From 0cc0882f08bc2d77be255e7432d4ac6c6550a5d4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:07:08 +0000 Subject: [PATCH 024/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6789 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 9 ++- doc/Section_commands.txt | 1 + doc/fix.html | 1 + doc/fix.txt | 1 + doc/fix_restrain.html | 150 ++++++++++++++++++++++++++++++++++++++ doc/fix_restrain.txt | 139 +++++++++++++++++++++++++++++++++++ 6 files changed, 297 insertions(+), 4 deletions(-) create mode 100644 doc/fix_restrain.html create mode 100644 doc/fix_restrain.txt diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 3671b787b1..17be7419e2 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -342,10 +342,11 @@ of each style or click on the style itself for a full description: langevinlineforcemomentummovemsstnebnphnph/asphere nph/spherenptnpt/aspherenpt/spherenvenve/aspherenve/limitnve/noforce nve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fccplaneforcepoems -pourpress/berendsenprintqeq/combreax/bondsrecenterrigidrigid/nve -rigid/nvtsetforceshakespringspring/rgspring/selfsrdstore/force -store/statetemp/berendsentemp/rescalethermal/conductivitytmdttmviscosityviscous -wall/colloidwall/granwall/harmonicwall/lj126wall/lj93wall/reflectwall/regionwall/srd +pourpress/berendsenprintqeq/combreax/bondsrecenterrestrainrigid +rigid/nverigid/nvtsetforceshakespringspring/rgspring/selfsrd +store/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmdttmviscosity +viscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93wall/reflectwall/region +wall/srd

    These are fix styles contributed by users, which can be used if diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 8bc22c3a49..2637513cc1 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -451,6 +451,7 @@ of each style or click on the style itself for a full description: "qeq/comb"_fix_qeq_comb.html, "reax/bonds"_fix_reax_bonds.html, "recenter"_fix_recenter.html, +"restrain"_fix_restrain.html, "rigid"_fix_rigid.html, "rigid/nve"_fix_rigid.html, "rigid/nvt"_fix_rigid.html, diff --git a/doc/fix.html b/doc/fix.html index 51d33fc88c..bd47e95a4d 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -211,6 +211,7 @@ list of fix styles available in LAMMPS:

  • press/berendsen - pressure control by Berendsen barostat
  • print - print text and variables during a simulation
  • reax/bonds - write out ReaxFF bond information recenter - constrain the center-of-mass position of a group of atoms +
  • restrain - constrain a bond, angle, dihedral
  • rigid - constrain one or more clusters of atoms to move as a rigid body with NVE integration
  • rigid/nve - constrain one or more clusters of atoms to move as a rigid body with alternate NVE integration
  • rigid/nvt - constrain one or more clusters of atoms to move as a rigid body with NVT integration diff --git a/doc/fix.txt b/doc/fix.txt index 4ab287ea7a..749bef0353 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -210,6 +210,7 @@ list of fix styles available in LAMMPS: "reax/bonds"_fix_reax_bonds.html - write out ReaxFF bond information \ "recenter"_fix_recenter.html - constrain the center-of-mass position \ of a group of atoms +"restrain"_fix_restrain.html - constrain a bond, angle, dihedral "rigid"_fix_rigid.html - constrain one or more clusters of atoms to \ move as a rigid body with NVE integration "rigid/nve"_fix_rigid.html - constrain one or more clusters of atoms to \ diff --git a/doc/fix_restrain.html b/doc/fix_restrain.html new file mode 100644 index 0000000000..606cad177d --- /dev/null +++ b/doc/fix_restrain.html @@ -0,0 +1,150 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    fix restrain command +

    +

    Syntax: +

    +
    fix ID group-ID restrain Kstart Kstop keyword value(s) 
    +
    +
    • ID, group-ID are documented in fix command + +
    • restrain = style name of this fix command + +
    • Kstart, Kstop = restraint coefficient at start/end of run (energy +units) + +
    • one keyword with one or more sets of parameter values may be appended to args + +
    • keyword = dihedral + +
        dihedral value = atom1 atom2 atom3 atom4 target
      +    atom1,atom2,atom3,atom4 = IDs of 4 atoms in restrained dihedral
      +    target = target value for specified dihedral angle (degrees) 
      +
      + +
    +

    Examples: +

    +
    fix holdem all restrain 2000.0 2000.0 dihedral 1 2 3 4 120.0
    +fix texas_holdem all restrain 0.0 2000.0 dihedral 1 2 3 4 120.0 1 2 3 5 -120.0 1 2 3 6 0.0 
    +
    +

    Description: +

    +

    Restrain the motion of the specified atoms by making them part of a +bond or angle or dihedral interaction whose strength can vary over +time during a simulation. This is functionally equivalent to creating +a bond or angle or dihedral for the atoms in a data file, as specified +by the read_data command, albeit with a time-varying +pre-factor coefficient. For the purpose of forcefield +parameter-fitting or mapping a molecular potential energy surface, +this fix reduces the hassle and risk associated with modifying data +files. In other words, use this fix to temporarily force a molecule +to adopt a particular conformation. To form a permanent bond or angle +or dihedral, modify the data file. +

    +

    The first example above applies a restraint to hold the dihedral angle +formed by atoms 1, 2, 3, and 4 near 120 degrees using a constant +restraint coefficient. The second example applies similar restraints +to multiple dihedral angles using a restraint coefficient that +increases from 0.0 to 2000.0 over the course of the run. +

    +

    IMPORTANT NOTE: Adding a force to atoms implies a change in their +potential energy as they move due to the applied force field. For +dynamics via the run command, this energy can be added to +the system's potential energy for thermodynamic output (see below). +For energy minimization via the minimize command, this +energy must be added to the system's potential energy to formulate a +self-consistent minimization problem (see below). +

    +

    In order for a restraint to be effective, the restraint force must +typically be significantly larger than the forces associated with +conventional forcefield terms. If the restraint is applied during a +dynamics run (as opposed to during an energy minimization), a large +restraint coefficient can significantly reduce the stable timestep +size, especially if the atoms are initially far from the preferred +conformation. You may need to experiment to determine what value of K +works best for a given application. +

    +

    For the case of finding a minimum energy structure for a single +molecule with particular restratins (e.g. for fitting forcefield +parameters or constructing a potential energy surface), commands such +as the following might be useful: +

    +
    # minimize molecule energy with restraints
    +velocity all create 600.0 8675309 mom yes rot yes dist gaussian
    +fix NVE all nve
    +fix TFIX all langevin 600.0 0.0 100 24601
    +fix REST all restrain 0.0 5000.0 dihedral 2 1 3 8 $angle1 3 1 2 9 $angle2
    +fix_modify REST energy yes
    +run 10000
    +fix TFIX all langevin 0.0 0.0 100 24601
    +fix REST all restrain 5000.0 5000.0 dihedral 2 1 3 8 $angle1 3 1 2 9 $angle2
    +fix_modify REST energy yes
    +run 10000
    +# sanity check for convergence
    +minimize 1e-6 1e-9 1000 100000
    +# report unrestrained energies
    +unfix REST
    +run 0 
    +
    +
    + +

    The dihedral keyword applies a dihedral restraint to the specified +atoms using a simplified form of the function used in dihedral_style +charmm. Specifically, the potential associated +with the restraint is +

    +
    +
    +

    with the following coefficients: +

    +
    • K (energy) = K (specified above) +
    • n = 1 +
    • d (degrees) = 180.0 + target (specified above) +
    +
    + +

    Restart, fix_modify, output, run start/stop, minimize info: +

    +

    No information about this fix is written to binary restart +files. +

    +

    The fix_modify energy option is supported by this +fix to add the potential energy associated with this fix to the +system's potential energy as part of thermodynamic +output. +

    +

    IMPORTANT NOTE: If you want the fictitious potential energy associated +with the added forces to be included in the total potential energy of +the system (the quantity being minimized), you MUST enable the +fix_modify energy option for this fix. +

    +

    This fix computes a global scalar, which can be accessed by various +output commands. The scalar is the +potential energy discussed above. The scalar value calculated by this +fix is "extensive". +

    +

    No parameter of this fix can be used with the start/stop keywords of +the run command. +

    +

    Restrictions: +

    +

    The group-ID specified by this fix is ignored. +

    +

    Currently, only dihedral restraints are allowed, but modification of +the code to allow angle and bond restraints would be straightforward. +

    +

    Related commands: none +

    +

    Default: none +

    + diff --git a/doc/fix_restrain.txt b/doc/fix_restrain.txt new file mode 100644 index 0000000000..5e38f9f597 --- /dev/null +++ b/doc/fix_restrain.txt @@ -0,0 +1,139 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix restrain command :h3 + +[Syntax:] + +fix ID group-ID restrain Kstart Kstop keyword value(s) :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +restrain = style name of this fix command :l +Kstart, Kstop = restraint coefficient at start/end of run (energy +units) :l +one keyword with one or more sets of parameter values may be appended to args :l +keyword = {dihedral} :l + {dihedral} value = atom1 atom2 atom3 atom4 target + atom1,atom2,atom3,atom4 = IDs of 4 atoms in restrained dihedral + target = target value for specified dihedral angle (degrees) :pre +:ule + +[Examples:] + +fix holdem all restrain 2000.0 2000.0 dihedral 1 2 3 4 120.0 +fix texas_holdem all restrain 0.0 2000.0 dihedral 1 2 3 4 120.0 1 2 3 5 -120.0 1 2 3 6 0.0 :pre + +[Description:] + +Restrain the motion of the specified atoms by making them part of a +bond or angle or dihedral interaction whose strength can vary over +time during a simulation. This is functionally equivalent to creating +a bond or angle or dihedral for the atoms in a data file, as specified +by the "read_data"_read_data.html command, albeit with a time-varying +pre-factor coefficient. For the purpose of forcefield +parameter-fitting or mapping a molecular potential energy surface, +this fix reduces the hassle and risk associated with modifying data +files. In other words, use this fix to temporarily force a molecule +to adopt a particular conformation. To form a permanent bond or angle +or dihedral, modify the data file. + +The first example above applies a restraint to hold the dihedral angle +formed by atoms 1, 2, 3, and 4 near 120 degrees using a constant +restraint coefficient. The second example applies similar restraints +to multiple dihedral angles using a restraint coefficient that +increases from 0.0 to 2000.0 over the course of the run. + +IMPORTANT NOTE: Adding a force to atoms implies a change in their +potential energy as they move due to the applied force field. For +dynamics via the "run"_run.html command, this energy can be added to +the system's potential energy for thermodynamic output (see below). +For energy minimization via the "minimize"_minimize.html command, this +energy must be added to the system's potential energy to formulate a +self-consistent minimization problem (see below). + +In order for a restraint to be effective, the restraint force must +typically be significantly larger than the forces associated with +conventional forcefield terms. If the restraint is applied during a +dynamics run (as opposed to during an energy minimization), a large +restraint coefficient can significantly reduce the stable timestep +size, especially if the atoms are initially far from the preferred +conformation. You may need to experiment to determine what value of K +works best for a given application. + +For the case of finding a minimum energy structure for a single +molecule with particular restratins (e.g. for fitting forcefield +parameters or constructing a potential energy surface), commands such +as the following might be useful: + +# minimize molecule energy with restraints +velocity all create 600.0 8675309 mom yes rot yes dist gaussian +fix NVE all nve +fix TFIX all langevin 600.0 0.0 100 24601 +fix REST all restrain 0.0 5000.0 dihedral 2 1 3 8 ${angle1} 3 1 2 9 ${angle2} +fix_modify REST energy yes +run 10000 +fix TFIX all langevin 0.0 0.0 100 24601 +fix REST all restrain 5000.0 5000.0 dihedral 2 1 3 8 ${angle1} 3 1 2 9 ${angle2} +fix_modify REST energy yes +run 10000 +# sanity check for convergence +minimize 1e-6 1e-9 1000 100000 +# report unrestrained energies +unfix REST +run 0 :pre + +:line + +The {dihedral} keyword applies a dihedral restraint to the specified +atoms using a simplified form of the function used in "dihedral_style +charmm"_dihedral_charmm.html. Specifically, the potential associated +with the restraint is + +:c,image(Eqs/dihedral_charmm.jpg) + +with the following coefficients: + +K (energy) = K (specified above) +n = 1 +d (degrees) = 180.0 + target (specified above) :ul + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. + +The "fix_modify"_fix_modify.html {energy} option is supported by this +fix to add the potential energy associated with this fix to the +system's potential energy as part of "thermodynamic +output"_thermo_style.html. + +IMPORTANT NOTE: If you want the fictitious potential energy associated +with the added forces to be included in the total potential energy of +the system (the quantity being minimized), you MUST enable the +"fix_modify"_fix_modify.html {energy} option for this fix. + +This fix computes a global scalar, which can be accessed by various +"output commands"_Section_howto.html#4_15. The scalar is the +potential energy discussed above. The scalar value calculated by this +fix is "extensive". + +No parameter of this fix can be used with the {start/stop} keywords of +the "run"_run.html command. + +[Restrictions:] + +The group-ID specified by this fix is ignored. + +Currently, only dihedral restraints are allowed, but modification of +the code to allow angle and bond restraints would be straightforward. + +[Related commands:] none + +[Default:] none From 158388f66cd7958f42c5160b3484f8068538d216 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:07:20 +0000 Subject: [PATCH 025/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6790 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_restrain.cpp | 401 +++++++++++++++++++++++++++++++++++++++++++ src/fix_restrain.h | 53 ++++++ 2 files changed, 454 insertions(+) create mode 100644 src/fix_restrain.cpp create mode 100644 src/fix_restrain.h diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp new file mode 100644 index 0000000000..a4e040f0c3 --- /dev/null +++ b/src/fix_restrain.cpp @@ -0,0 +1,401 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Craig Tenney (University of Notre Dame) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" +#include "stdlib.h" +#include "fix_restrain.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "domain.h" +#include "comm.h" +#include "respa.h" +#include "input.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +enum{DIHEDRAL}; + +#define TOLERANCE 0.05 + +/* ---------------------------------------------------------------------- */ + +FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + int iarg = 6; + if (narg < iarg) error->all("Illegal fix restrain command"); + + scalar_flag = 1; + global_freq = 1; + extscalar = 1; + time_depend = 1; + + // parse standard arguments + + int n_atoms; + k_start = force->numeric(arg[3]); + k_stop = force->numeric(arg[4]); + if (strcmp(arg[5], "dihedral") == 0) { + rstyle = DIHEDRAL; + n_atoms = 4; + } else error->all("Illegal fix restrain command"); + + n_bonds = (narg - iarg) / (n_atoms + 1); + if (narg != iarg + n_bonds * (n_atoms + 1)) + error->all("Illegal fix restrain command"); + + // allocate arrays + + memory->create(atom_id,n_bonds,n_atoms,"restrain:atom_id"); + memory->create(target,n_bonds,"restrain:taret"); + + // grab atom_ids and restraint target values + + int ibond = 0; + while (iarg < narg) { + for (int i = 0; i < n_atoms; i++) { + atom_id[ibond][i] = force->inumeric(arg[iarg]); + iarg++; + } + target[ibond] = force->numeric(arg[iarg]); + iarg++; + ibond++; + } + + // special treatment for dihedral restraints + + if (rstyle == DIHEDRAL) { + double PI = 4.0*atan(1.0); + cos_shift = (double *) + memory->smalloc(n_bonds * sizeof(double), "restrain:cos_shift"); + sin_shift = (double *) + memory->smalloc(n_bonds * sizeof(double), "restrain:sin_shift"); + for (ibond = 0; ibond < n_bonds; ibond++) { + double my_arg = PI * (180.0 + target[ibond]) / 180.0; + cos_shift[ibond] = cos(my_arg); + sin_shift[ibond] = sin(my_arg); + } + } + + // require atom map to lookup atom IDs + + if (atom->map_style == 0) + error->all("Fix restrain requires an atom map, see atom_modify"); +} + +/* ---------------------------------------------------------------------- */ + +FixRestrain::~FixRestrain() +{ + memory->destroy(atom_id); + memory->destroy(target); + + if (rstyle == DIHEDRAL) { + memory->sfree(cos_shift); + memory->sfree(sin_shift); + } +} + +/* ---------------------------------------------------------------------- */ + +int FixRestrain::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + mask |= THERMO_ENERGY; + mask |= POST_FORCE_RESPA; + mask |= MIN_POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::init() +{ + if (strcmp(update->integrate_style,"respa") == 0) + nlevels_respa = ((Respa *) update->integrate)->nlevels; +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::setup(int vflag) +{ + if (strcmp(update->integrate_style,"verlet") == 0) + post_force(vflag); + else { + ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1); + post_force_respa(vflag,nlevels_respa-1,0); + ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::min_setup(int vflag) +{ + post_force(vflag); +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::post_force(int vflag) +{ + energy = 0.0; + if (rstyle == DIHEDRAL) restrain_dihedral(); +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::post_force_respa(int vflag, int ilevel, int iloop) +{ + if (ilevel == nlevels_respa-1) post_force(vflag); +} + +/* ---------------------------------------------------------------------- */ + +void FixRestrain::min_post_force(int vflag) +{ + post_force(vflag); +} + +/* ---------------------------------------------------------------------- + apply dihedral restraints + adopted from dihedral_charmm +---------------------------------------------------------------------- */ + +void FixRestrain::restrain_dihedral() +{ + int i1,i2,i3,i4,i,m,n; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double f1[3],f2[3],f3[3],f4[3]; + double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; + double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; + double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; + double c,s,p,sx2,sy2,sz2; + + double **x = atom->x; + double **f = atom->f; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + double delta = update->ntimestep - update->beginstep; + delta /= update->endstep - update->beginstep; + + double k_step = k_start + delta * (k_stop - k_start); + + for (n = 0; n < n_bonds; n++) { + i1 = atom->map(atom_id[n][0]); + i2 = atom->map(atom_id[n][1]); + i3 = atom->map(atom_id[n][2]); + i4 = atom->map(atom_id[n][3]); + + // insure exactly one processor computes restraint + + if (newton_bond) { + if (i2 == -1 || i2 >= nlocal) continue; + if (i1 == -1 || i3 == -1 || i4 == -1) { + char str[128]; + sprintf(str, + "Restrain atoms %d %d %d %d missing on proc %d at step " + BIGINT_FORMAT, + atom_id[n][0],atom_id[n][1],atom_id[n][2],atom_id[n][3], + comm->me,update->ntimestep); + error->one(str); + } + } else { + if ((i1 == -1 || i1 >= nlocal) && (i2 == -1 || i2 >= nlocal) && + (i3 == -1 || i3 >= nlocal) && (i4 == -1 || i3 >= nlocal)) continue; + if (i1 == -1 || i2 == -1 || i3 == -1 || i4 == -1) { + char str[128]; + sprintf(str, + "Restrain atoms %d %d %d %d missing on proc %d at step " + BIGINT_FORMAT, + atom_id[n][0],atom_id[n][1],atom_id[n][2],atom_id[n][3], + comm->me,update->ntimestep); + error->one(str); + } + } + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + ax = vb1y*vb2zm - vb1z*vb2ym; + ay = vb1z*vb2xm - vb1x*vb2zm; + az = vb1x*vb2ym - vb1y*vb2xm; + bx = vb3y*vb2zm - vb3z*vb2ym; + by = vb3z*vb2xm - vb3x*vb2zm; + bz = vb3x*vb2ym - vb3y*vb2xm; + + rasq = ax*ax + ay*ay + az*az; + rbsq = bx*bx + by*by + bz*bz; + rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; + rg = sqrt(rgsq); + + rginv = ra2inv = rb2inv = 0.0; + if (rg > 0) rginv = 1.0/rg; + if (rasq > 0) ra2inv = 1.0/rasq; + if (rbsq > 0) rb2inv = 1.0/rbsq; + rabinv = sqrt(ra2inv*rb2inv); + + c = (ax*bx + ay*by + az*bz)*rabinv; + s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me; + MPI_Comm_rank(world,&me); + if (screen) { + char str[128]; + sprintf(str,"Restrain problem: %d %d %d %d %d %d", + me,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(str); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + m = 1; //multiplicity + p = 1.0; + df1 = 0.0; + + for (i = 0; i < m; i++) { + ddf1 = p*c - df1*s; + df1 = p*s + df1*c; + p = ddf1; + } + + p = p*cos_shift[n] + df1*sin_shift[n]; + df1 = df1*cos_shift[n] - ddf1*sin_shift[n]; + df1 *= -m; + p += 1.0; + + energy = k_step * p; + + fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; + hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; + fga = fg*ra2inv*rginv; + hgb = hg*rb2inv*rginv; + gaa = -ra2inv*rg; + gbb = rb2inv*rg; + + dtfx = gaa*ax; + dtfy = gaa*ay; + dtfz = gaa*az; + dtgx = fga*ax - hgb*bx; + dtgy = fga*ay - hgb*by; + dtgz = fga*az - hgb*bz; + dthx = gbb*bx; + dthy = gbb*by; + dthz = gbb*bz; + + df = -k_step * df1; + + sx2 = df*dtgx; + sy2 = df*dtgy; + sz2 = df*dtgz; + + f1[0] = df*dtfx; + f1[1] = df*dtfy; + f1[2] = df*dtfz; + + f2[0] = sx2 - f1[0]; + f2[1] = sy2 - f1[1]; + f2[2] = sz2 - f1[2]; + + f4[0] = df*dthx; + f4[1] = df*dthy; + f4[2] = df*dthz; + + f3[0] = -sx2 - f4[0]; + f3[1] = -sy2 - f4[1]; + f3[2] = -sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (newton_bond || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (newton_bond || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (newton_bond || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (newton_bond || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + } +} + +/* ---------------------------------------------------------------------- + potential energy of added force +------------------------------------------------------------------------- */ + +double FixRestrain::compute_scalar() +{ + MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); + return energy_all; +} diff --git a/src/fix_restrain.h b/src/fix_restrain.h new file mode 100644 index 0000000000..c540459092 --- /dev/null +++ b/src/fix_restrain.h @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(restrain,FixRestrain) + +#else + +#ifndef LMP_FIX_RESTRAIN_H +#define LMP_FIX_RESTRAIN_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixRestrain : public Fix { + public: + FixRestrain(class LAMMPS *, int, char **); + ~FixRestrain(); + int setmask(); + void init(); + void setup(int); + void min_setup(int); + void post_force(int); + void post_force_respa(int, int, int); + void min_post_force(int); + double compute_scalar(); + + private: + int nlevels_respa; + int n_bonds, rstyle; + double k_start, k_stop, energy, energy_all; + int **atom_id; + double *target, *cos_shift, *sin_shift; + + void restrain_dihedral(); +}; + +} + +#endif +#endif From eb915e1174df612afbce892b2d8faa2d97ed8356 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:10:07 +0000 Subject: [PATCH 026/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6792 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index c76581f30c..50af95af92 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "23 Aug 2011" +#define LAMMPS_VERSION "24 Aug 2011" From b19a38a92d19056d88a911b12577f68e2b5c98fa Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:29:48 +0000 Subject: [PATCH 027/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6794 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MOLECULE/Install.sh | 12 - src/MOLECULE/fix_bond_break.cpp | 392 ------------------ src/MOLECULE/fix_bond_break.h | 60 --- src/MOLECULE/fix_bond_create.cpp | 617 --------------------------- src/MOLECULE/fix_bond_create.h | 74 ---- src/MOLECULE/fix_bond_swap.cpp | 689 ------------------------------- src/MOLECULE/fix_bond_swap.h | 63 --- 7 files changed, 1907 deletions(-) delete mode 100755 src/MOLECULE/fix_bond_break.cpp delete mode 100755 src/MOLECULE/fix_bond_break.h delete mode 100755 src/MOLECULE/fix_bond_create.cpp delete mode 100755 src/MOLECULE/fix_bond_create.h delete mode 100644 src/MOLECULE/fix_bond_swap.cpp delete mode 100644 src/MOLECULE/fix_bond_swap.h diff --git a/src/MOLECULE/Install.sh b/src/MOLECULE/Install.sh index e04276c460..58deb45525 100644 --- a/src/MOLECULE/Install.sh +++ b/src/MOLECULE/Install.sh @@ -27,9 +27,6 @@ if (test $1 = 1) then cp dihedral_hybrid.cpp .. cp dihedral_multi_harmonic.cpp .. cp dihedral_opls.cpp .. - cp fix_bond_break.cpp .. - cp fix_bond_create.cpp .. - cp fix_bond_swap.cpp .. cp improper_cvff.cpp .. cp improper_harmonic.cpp .. cp improper_hybrid.cpp .. @@ -64,9 +61,6 @@ if (test $1 = 1) then cp dihedral_hybrid.h .. cp dihedral_multi_harmonic.h .. cp dihedral_opls.h .. - cp fix_bond_break.h .. - cp fix_bond_create.h .. - cp fix_bond_swap.h .. cp improper_cvff.h .. cp improper_harmonic.h .. cp improper_hybrid.h .. @@ -103,9 +97,6 @@ elif (test $1 = 0) then rm -f ../dihedral_hybrid.cpp rm -f ../dihedral_multi_harmonic.cpp rm -f ../dihedral_opls.cpp - rm -f ../fix_bond_break.cpp - rm -f ../fix_bond_create.cpp - rm -f ../fix_bond_swap.cpp rm -f ../improper_cvff.cpp rm -f ../improper_harmonic.cpp rm -f ../improper_hybrid.cpp @@ -140,9 +131,6 @@ elif (test $1 = 0) then rm -f ../dihedral_hybrid.h rm -f ../dihedral_multi_harmonic.h rm -f ../dihedral_opls.h - rm -f ../fix_bond_break.h - rm -f ../fix_bond_create.h - rm -f ../fix_bond_swap.h rm -f ../improper_cvff.h rm -f ../improper_harmonic.h rm -f ../improper_hybrid.h diff --git a/src/MOLECULE/fix_bond_break.cpp b/src/MOLECULE/fix_bond_break.cpp deleted file mode 100755 index a4c44338da..0000000000 --- a/src/MOLECULE/fix_bond_break.cpp +++ /dev/null @@ -1,392 +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 "math.h" -#include "mpi.h" -#include "string.h" -#include "stdlib.h" -#include "fix_bond_break.h" -#include "update.h" -#include "respa.h" -#include "atom.h" -#include "force.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "random_mars.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) - -/* ---------------------------------------------------------------------- */ - -FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) -{ - if (narg < 6) error->all("Illegal fix bond/break command"); - - MPI_Comm_rank(world,&me); - - nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix bond/break command"); - - force_reneighbor = 1; - next_reneighbor = -1; - vector_flag = 1; - size_vector = 2; - global_freq = 1; - extvector = 0; - - btype = atoi(arg[4]); - double cutoff = atof(arg[5]); - - if (btype < 1 || btype > atom->nbondtypes) - error->all("Invalid bond type in fix bond/break command"); - if (cutoff < 0.0) error->all("Illegal fix bond/break command"); - - cutsq = cutoff*cutoff; - - // optional keywords - - fraction = 1.0; - int seed = 12345; - - int iarg = 6; - while (iarg < narg) { - if (strcmp(arg[iarg],"prob") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/break command"); - fraction = atof(arg[iarg+1]); - seed = atoi(arg[iarg+2]); - if (fraction < 0.0 || fraction > 1.0) - error->all("Illegal fix bond/break command"); - if (seed <= 0) error->all("Illegal fix bond/break command"); - iarg += 3; - } else error->all("Illegal fix bond/break command"); - } - - // error check - - if (atom->molecular == 0) - error->all("Cannot use fix bond/break with non-molecular systems"); - - // initialize Marsaglia RNG with processor-unique seed - - random = new RanMars(lmp,seed + me); - - // set comm sizes needed by this fix - - comm_forward = 2; - comm_reverse = 2; - - // allocate arrays local to this fix - - nmax = 0; - partner = NULL; - distsq = NULL; - - // zero out stats - - breakcount = 0; - breakcounttotal = 0; -} - -/* ---------------------------------------------------------------------- */ - -FixBondBreak::~FixBondBreak() -{ - delete random; - - // delete locally stored arrays - - memory->destroy(partner); - memory->destroy(distsq); -} - -/* ---------------------------------------------------------------------- */ - -int FixBondBreak::setmask() -{ - int mask = 0; - mask |= POST_INTEGRATE; - mask |= POST_INTEGRATE_RESPA; - return mask; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondBreak::init() -{ - // require special bonds = 0,1,1 - - int flag = 0; - if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || - force->special_lj[3] != 1.0) flag = 1; - if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || - force->special_coul[3] != 1.0) flag = 1; - if (flag) error->all("Fix bond/break requires special_bonds = 0,1,1"); - - // warn if angles, dihedrals, impropers are being used - - if (force->angle || force->dihedral || force->improper) { - if (me == 0) - error->warning("Broken bonds will not alter angles, " - "dihedrals, or impropers"); - } - - if (strstr(update->integrate_style,"respa")) - nlevels_respa = ((Respa *) update->integrate)->nlevels; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondBreak::post_integrate() -{ - int i,j,k,m,n,i1,i2,n1,n3,type; - double delx,dely,delz,rsq,min,max; - int *slist; - - if (update->ntimestep % nevery) return; - - // need updated ghost atom positions - - comm->forward_comm(); - - // resize bond partner list and initialize it - // probability array overlays distsq array - // needs to be atom->nmax in length - - if (atom->nmax > nmax) { - memory->destroy(partner); - memory->destroy(distsq); - nmax = atom->nmax; - memory->create(partner,nmax,"bond/break:partner"); - memory->create(distsq,nmax,"bond/break:distsq"); - probability = distsq; - } - - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - - for (i = 0; i < nall; i++) { - partner[i] = 0; - distsq[i] = 0.0; - } - - // loop over bond list - // setup possible partner list of bonds to break - - double **x = atom->x; - int *tag = atom->tag; - int *mask = atom->mask; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - - for (n = 0; n < nbondlist; n++) { - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - if (!(mask[i1] & groupbit)) continue; - if (!(mask[i2] & groupbit)) continue; - if (type != btype) continue; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(delx,dely,delz); - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutsq) continue; - - if (rsq > distsq[i1]) { - partner[i1] = tag[i2]; - distsq[i1] = rsq; - } - if (rsq > distsq[i2]) { - partner[i2] = tag[i1]; - distsq[i2] = rsq; - } - } - - // reverse comm of partner info - - if (force->newton_bond) comm->reverse_comm_fix(this); - - // each atom now knows its winning partner - // for prob check, generate random value for each atom with a bond partner - // forward comm of partner and random value, so ghosts have it - - if (fraction < 1.0) { - for (i = 0; i < nlocal; i++) - if (partner[i]) probability[i] = random->uniform(); - } - - comm->forward_comm_fix(this); - - // break bonds - // if both atoms list each other as winning bond partner - // and probability constraint is satisfied - - int **bond_type = atom->bond_type; - int **bond_atom = atom->bond_atom; - int *num_bond = atom->num_bond; - int **nspecial = atom->nspecial; - int **special = atom->special; - - int nbreak = 0; - for (i = 0; i < nlocal; i++) { - if (partner[i] == 0) continue; - j = atom->map(partner[i]); - if (partner[j] != tag[i]) continue; - - // apply probability constraint - // MIN,MAX insures values are added in same order on different procs - - if (fraction < 1.0) { - min = MIN(probability[i],probability[j]); - max = MAX(probability[i],probability[j]); - if (0.5*(min+max) >= fraction) continue; - } - - // delete bond from atom I if I stores it - // atom J will also do this - - for (m = 0; m < num_bond[i]; m++) { - if (bond_atom[i][m] == partner[i]) { - for (k = m; k < num_bond[i]-1; k++) { - bond_atom[i][k] = bond_atom[i][k+1]; - bond_type[i][k] = bond_type[i][k+1]; - } - num_bond[i]--; - break; - } - } - - // remove J from special bond list for atom I - // atom J will also do this - - slist = special[i]; - n1 = nspecial[i][0]; - n3 = nspecial[i][2]; - for (m = 0; m < n1; m++) - if (slist[m] == partner[i]) break; - for (; m < n3-1; m++) slist[m] = slist[m+1]; - nspecial[i][0]--; - nspecial[i][1]--; - nspecial[i][2]--; - - // count the broken bond once - - if (tag[i] < tag[j]) nbreak++; - } - - // tally stats - - MPI_Allreduce(&nbreak,&breakcount,1,MPI_INT,MPI_SUM,world); - breakcounttotal += breakcount; - atom->nbonds -= breakcount; - - // trigger reneighboring if any bonds were formed - - if (breakcount) next_reneighbor = update->ntimestep; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondBreak::post_integrate_respa(int ilevel, int iloop) -{ - if (ilevel == nlevels_respa-1) post_integrate(); -} - -/* ---------------------------------------------------------------------- */ - -int FixBondBreak::pack_comm(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = partner[j]; - buf[m++] = probability[j]; - } - return 2; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondBreak::unpack_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - partner[i] = static_cast (buf[m++]); - probability[i] = buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -int FixBondBreak::pack_reverse_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - buf[m++] = partner[i]; - buf[m++] = distsq[i]; - } - return 2; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondBreak::unpack_reverse_comm(int n, int *list, double *buf) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - if (buf[m+1] > distsq[j]) { - partner[j] = static_cast (buf[m++]); - distsq[j] = buf[m++]; - } else m += 2; - } -} - -/* ---------------------------------------------------------------------- */ - -double FixBondBreak::compute_vector(int n) -{ - if (n == 1) return (double) breakcount; - return (double) breakcounttotal; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays -------------------------------------------------------------------------- */ - -double FixBondBreak::memory_usage() -{ - int nmax = atom->nmax; - double bytes = nmax * sizeof(int); - bytes += nmax * sizeof(double); - return bytes; -} diff --git a/src/MOLECULE/fix_bond_break.h b/src/MOLECULE/fix_bond_break.h deleted file mode 100755 index 597a7e93f3..0000000000 --- a/src/MOLECULE/fix_bond_break.h +++ /dev/null @@ -1,60 +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. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(bond/break,FixBondBreak) - -#else - -#ifndef LMP_FIX_BOND_BREAK_H -#define LMP_FIX_BOND_BREAK_H - -#include "fix.h" - -namespace LAMMPS_NS { - -class FixBondBreak : public Fix { - public: - FixBondBreak(class LAMMPS *, int, char **); - ~FixBondBreak(); - int setmask(); - void init(); - void post_integrate(); - void post_integrate_respa(int,int); - - int pack_comm(int, int *, double *, int, int *); - void unpack_comm(int, int, double *); - int pack_reverse_comm(int, int, double *); - void unpack_reverse_comm(int, int *, double *); - double compute_vector(int); - double memory_usage(); - - private: - int me; - int btype,seed; - double cutsq,fraction; - - int breakcount,breakcounttotal; - int nmax; - int *partner; - double *distsq,*probability; - - class RanMars *random; - int nlevels_respa; -}; - -} - -#endif -#endif diff --git a/src/MOLECULE/fix_bond_create.cpp b/src/MOLECULE/fix_bond_create.cpp deleted file mode 100755 index 295f04981b..0000000000 --- a/src/MOLECULE/fix_bond_create.cpp +++ /dev/null @@ -1,617 +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 "math.h" -#include "mpi.h" -#include "string.h" -#include "stdlib.h" -#include "fix_bond_create.h" -#include "update.h" -#include "respa.h" -#include "atom.h" -#include "force.h" -#include "pair.h" -#include "comm.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "random_mars.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define BIG 1.0e20 - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -/* ---------------------------------------------------------------------- */ - -FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) -{ - if (narg < 8) error->all("Illegal fix bond/create command"); - - MPI_Comm_rank(world,&me); - - nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix bond/create command"); - - force_reneighbor = 1; - next_reneighbor = -1; - vector_flag = 1; - size_vector = 2; - global_freq = 1; - extvector = 0; - - iatomtype = atoi(arg[4]); - jatomtype = atoi(arg[5]); - double cutoff = atof(arg[6]); - btype = atoi(arg[7]); - - if (iatomtype < 1 || iatomtype > atom->ntypes || - jatomtype < 1 || jatomtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); - if (cutoff < 0.0) error->all("Illegal fix bond/create command"); - if (btype < 1 || btype > atom->nbondtypes) - error->all("Invalid bond type in fix bond/create command"); - - cutsq = cutoff*cutoff; - - // optional keywords - - imaxbond = 0; - inewtype = iatomtype; - jmaxbond = 0; - jnewtype = jatomtype; - fraction = 1.0; - int seed = 12345; - - int iarg = 8; - while (iarg < narg) { - if (strcmp(arg[iarg],"iparam") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); - imaxbond = atoi(arg[iarg+1]); - inewtype = atoi(arg[iarg+2]); - if (imaxbond < 0) error->all("Illegal fix bond/create command"); - if (inewtype < 1 || inewtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); - iarg += 3; - } else if (strcmp(arg[iarg],"jparam") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); - jmaxbond = atoi(arg[iarg+1]); - jnewtype = atoi(arg[iarg+2]); - if (jmaxbond < 0) error->all("Illegal fix bond/create command"); - if (jnewtype < 1 || jnewtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); - iarg += 3; - } else if (strcmp(arg[iarg],"prob") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); - fraction = atof(arg[iarg+1]); - seed = atoi(arg[iarg+2]); - if (fraction < 0.0 || fraction > 1.0) - error->all("Illegal fix bond/create command"); - if (seed <= 0) error->all("Illegal fix bond/create command"); - iarg += 3; - } else error->all("Illegal fix bond/create command"); - } - - // error check - - if (atom->molecular == 0) - error->all("Cannot use fix bond/create with non-molecular systems"); - if (iatomtype == jatomtype && - ((imaxbond != jmaxbond) || (inewtype != jnewtype))) - error->all("Inconsistent iparam/jparam values in fix bond/create command"); - - // initialize Marsaglia RNG with processor-unique seed - - random = new RanMars(lmp,seed + me); - - // perform initial allocation of atom-based arrays - // register with Atom class - // bondcount values will be initialized in setup() - - bondcount = NULL; - grow_arrays(atom->nmax); - atom->add_callback(0); - countflag = 0; - - // set comm sizes needed by this fix - - comm_forward = 2; - comm_reverse = 2; - - // allocate arrays local to this fix - - nmax = 0; - partner = NULL; - distsq = NULL; - - // zero out stats - - createcount = 0; - createcounttotal = 0; -} - -/* ---------------------------------------------------------------------- */ - -FixBondCreate::~FixBondCreate() -{ - // unregister callbacks to this fix from Atom class - - atom->delete_callback(id,0); - - delete random; - - // delete locally stored arrays - - memory->destroy(bondcount); - memory->destroy(partner); - memory->destroy(distsq); -} - -/* ---------------------------------------------------------------------- */ - -int FixBondCreate::setmask() -{ - int mask = 0; - mask |= POST_INTEGRATE; - mask |= POST_INTEGRATE_RESPA; - return mask; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::init() -{ - // check cutoff for iatomtype,jatomtype - - if (force->pair == NULL || cutsq > force->pair->cutsq[iatomtype][jatomtype]) - error->all("Fix bond/create cutoff is longer than pairwise cutoff"); - - // require special bonds = 0,1,1 - - if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || - force->special_lj[3] != 1.0) - error->all("Fix bond/create requires special_bonds lj = 0,1,1"); - - if (atom->q_flag) - if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || - force->special_coul[3] != 1.0) - error->all("Fix bond/create requires special_bonds coul = 0,1,1"); - - // warn if angles, dihedrals, impropers are being used - - if (force->angle || force->dihedral || force->improper) { - if (me == 0) - error->warning("Created bonds will not create angles, " - "dihedrals, or impropers"); - } - - // need a half neighbor list, built when ever re-neighboring occurs - - int irequest = neighbor->request((void *) this); - neighbor->requests[irequest]->pair = 0; - neighbor->requests[irequest]->fix = 1; - - if (strstr(update->integrate_style,"respa")) - nlevels_respa = ((Respa *) update->integrate)->nlevels; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::init_list(int id, NeighList *ptr) -{ - list = ptr; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::setup(int vflag) -{ - int i,j,m; - - // compute initial bondcount if this is first run - // can't do this earlier, like in constructor or init, b/c need ghost info - - if (countflag) return; - countflag = 1; - - // count bonds stored with each bond I own - // if newton bond is not set, just increment count on atom I - // if newton bond is set, also increment count on atom J even if ghost - // bondcount is long enough to tally ghost atom counts - - int *num_bond = atom->num_bond; - int **bond_type = atom->bond_type; - int **bond_atom = atom->bond_atom; - int nlocal = atom->nlocal; - int nghost = atom->nghost; - int nall = nlocal + nghost; - int newton_bond = force->newton_bond; - - for (i = 0; i < nall; i++) bondcount[i] = 0; - - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_bond[i]; j++) { - if (bond_type[i][j] == btype) { - bondcount[i]++; - if (newton_bond) { - m = atom->map(bond_atom[i][j]); - if (m < 0) - error->one("Could not count initial bonds in fix bond/create"); - bondcount[m]++; - } - } - } - - // if newton_bond is set, need to sum bondcount - - commflag = 0; - if (newton_bond) comm->reverse_comm_fix(this); -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::post_integrate() -{ - int i,j,m,ii,jj,inum,jnum,itype,jtype,n1,n3,possible; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq,min,max; - int *ilist,*jlist,*numneigh,**firstneigh,*slist; - - if (update->ntimestep % nevery) return; - - // need updated ghost atom positions - - comm->forward_comm(); - - // forward comm of bondcount, so ghosts have it - - commflag = 0; - comm->forward_comm_fix(this); - - // resize bond partner list and initialize it - // probability array overlays distsq array - // needs to be atom->nmax in length - - if (atom->nmax > nmax) { - memory->destroy(partner); - memory->destroy(distsq); - nmax = atom->nmax; - memory->create(partner,nmax,"bond/create:partner"); - memory->create(distsq,nmax,"bond/create:distsq"); - probability = distsq; - } - - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - - for (i = 0; i < nall; i++) { - partner[i] = 0; - distsq[i] = BIG; - } - - // loop over neighbors of my atoms - // each atom sets one closest eligible partner atom ID to bond with - - double **x = atom->x; - int *tag = atom->tag; - int *mask = atom->mask; - int *type = atom->type; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - if (!(mask[i] & groupbit)) continue; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - if (!(mask[j] & groupbit)) continue; - jtype = type[j]; - - possible = 0; - if (itype == iatomtype && jtype == jatomtype) { - if ((imaxbond == 0 || bondcount[i] < imaxbond) && - (jmaxbond == 0 || bondcount[j] < jmaxbond)) - possible = 1; - } else if (itype == jatomtype && jtype == iatomtype) { - if ((jmaxbond == 0 || bondcount[i] < jmaxbond) && - (imaxbond == 0 || bondcount[j] < imaxbond)) - possible = 1; - } - if (!possible) 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 >= cutsq) continue; - - if (rsq < distsq[i]) { - partner[i] = tag[j]; - distsq[i] = rsq; - } - if (rsq < distsq[j]) { - partner[j] = tag[i]; - distsq[j] = rsq; - } - } - } - - // reverse comm of distsq and partner - // not needed if newton_pair off since I,J pair was seen by both procs - - commflag = 1; - if (force->newton_pair) comm->reverse_comm_fix(this); - - // each atom now knows its winning partner - // for prob check, generate random value for each atom with a bond partner - // forward comm of partner and random value, so ghosts have it - - if (fraction < 1.0) { - for (i = 0; i < nlocal; i++) - if (partner[i]) probability[i] = random->uniform(); - } - - commflag = 1; - comm->forward_comm_fix(this); - - // create bonds for atoms I own - // if other atom is owned by another proc, it should create same bond - // if both atoms list each other as winning bond partner - // and probability constraint is satisfied - - int **bond_type = atom->bond_type; - int **bond_atom = atom->bond_atom; - int *num_bond = atom->num_bond; - int **nspecial = atom->nspecial; - int **special = atom->special; - int newton_bond = force->newton_bond; - - int ncreate = 0; - for (i = 0; i < nlocal; i++) { - if (partner[i] == 0) continue; - j = atom->map(partner[i]); - if (partner[j] != tag[i]) continue; - - // apply probability constraint - // MIN,MAX insures values are added in same order on different procs - - if (fraction < 1.0) { - min = MIN(probability[i],probability[j]); - max = MAX(probability[i],probability[j]); - if (0.5*(min+max) >= fraction) continue; - } - - // if newton_bond is set, only store with I or J - // if not newton_bond, store bond with both I and J - - if (!newton_bond || tag[i] < tag[j]) { - if (num_bond[i] == atom->bond_per_atom) - error->one("New bond exceeded bonds per atom in fix bond/create"); - bond_type[i][num_bond[i]] = btype; - bond_atom[i][num_bond[i]] = tag[j]; - num_bond[i]++; - } - - // add a 1-2 neighbor to special bond list for atom I - // atom J will also do this - - slist = special[i]; - n1 = nspecial[i][0]; - n3 = nspecial[i][2]; - if (n3 == atom->maxspecial) - error->one("New bond exceeded special list size in fix bond/create"); - for (m = n3; m > n1; m--) slist[m+1] = slist[m]; - slist[n1] = tag[j]; - nspecial[i][0]++; - nspecial[i][1]++; - nspecial[i][2]++; - - // increment bondcount, convert atom to new type if limit reached - - bondcount[i]++; - if (type[i] == iatomtype) { - if (bondcount[i] == imaxbond) type[i] = inewtype; - } else { - if (bondcount[i] == jmaxbond) type[i] = jnewtype; - } - - // count the created bond once - - if (tag[i] < tag[j]) ncreate++; - } - - // tally stats - - MPI_Allreduce(&ncreate,&createcount,1,MPI_INT,MPI_SUM,world); - createcounttotal += createcount; - atom->nbonds += createcount; - - // trigger reneighboring if any bonds were formed - - if (createcount) next_reneighbor = update->ntimestep; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::post_integrate_respa(int ilevel, int iloop) -{ - if (ilevel == nlevels_respa-1) post_integrate(); -} - -/* ---------------------------------------------------------------------- */ - -int FixBondCreate::pack_comm(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - - m = 0; - - if (commflag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = bondcount[j]; - } - return 1; - - } else { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = partner[j]; - buf[m++] = probability[j]; - } - return 2; - } -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::unpack_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - - if (commflag == 0) { - for (i = first; i < last; i++) - bondcount[i] = static_cast (buf[m++]); - - } else { - for (i = first; i < last; i++) { - partner[i] = static_cast (buf[m++]); - probability[i] = buf[m++]; - } - } -} - -/* ---------------------------------------------------------------------- */ - -int FixBondCreate::pack_reverse_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - - if (commflag == 0) { - for (i = first; i < last; i++) - buf[m++] = bondcount[i]; - return 1; - - } else { - for (i = first; i < last; i++) { - buf[m++] = distsq[i]; - buf[m++] = partner[i]; - } - return 2; - } -} - -/* ---------------------------------------------------------------------- */ - -void FixBondCreate::unpack_reverse_comm(int n, int *list, double *buf) -{ - int i,j,m; - - m = 0; - - if (commflag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - bondcount[j] += static_cast (buf[m++]); - } - - } else { - for (i = 0; i < n; i++) { - j = list[i]; - if (buf[m] < distsq[j]) { - distsq[j] = buf[m++]; - partner[j] = static_cast (buf[m++]); - } else m += 2; - } - } -} - -/* ---------------------------------------------------------------------- - allocate local atom-based arrays -------------------------------------------------------------------------- */ - -void FixBondCreate::grow_arrays(int nmax) -{ - memory->grow(bondcount,nmax,"bond/create:bondcount"); -} - -/* ---------------------------------------------------------------------- - copy values within local atom-based arrays -------------------------------------------------------------------------- */ - -void FixBondCreate::copy_arrays(int i, int j) -{ - bondcount[j] = bondcount[i]; -} - -/* ---------------------------------------------------------------------- - pack values in local atom-based arrays for exchange with another proc -------------------------------------------------------------------------- */ - -int FixBondCreate::pack_exchange(int i, double *buf) -{ - buf[0] = bondcount[i]; - return 1; -} - -/* ---------------------------------------------------------------------- - unpack values in local atom-based arrays from exchange with another proc -------------------------------------------------------------------------- */ - -int FixBondCreate::unpack_exchange(int nlocal, double *buf) -{ - bondcount[nlocal] = static_cast (buf[0]); - return 1; -} - -/* ---------------------------------------------------------------------- */ - -double FixBondCreate::compute_vector(int n) -{ - if (n == 1) return (double) createcount; - return (double) createcounttotal; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays -------------------------------------------------------------------------- */ - -double FixBondCreate::memory_usage() -{ - int nmax = atom->nmax; - double bytes = nmax*2 * sizeof(int); - bytes += nmax * sizeof(double); - return bytes; -} diff --git a/src/MOLECULE/fix_bond_create.h b/src/MOLECULE/fix_bond_create.h deleted file mode 100755 index a54fd5d82a..0000000000 --- a/src/MOLECULE/fix_bond_create.h +++ /dev/null @@ -1,74 +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. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(bond/create,FixBondCreate) - -#else - -#ifndef LMP_FIX_BOND_CREATE_H -#define LMP_FIX_BOND_CREATE_H - -#include "fix.h" - -namespace LAMMPS_NS { - -class FixBondCreate : public Fix { - public: - FixBondCreate(class LAMMPS *, int, char **); - ~FixBondCreate(); - int setmask(); - void init(); - void init_list(int, class NeighList *); - void setup(int); - void post_integrate(); - void post_integrate_respa(int, int); - - int pack_comm(int, int *, double *, int, int *); - void unpack_comm(int, int, double *); - int pack_reverse_comm(int, int, double *); - void unpack_reverse_comm(int, int *, double *); - void grow_arrays(int); - void copy_arrays(int, int); - int pack_exchange(int, double *); - int unpack_exchange(int, double *); - double compute_vector(int); - double memory_usage(); - - private: - int me; - int iatomtype,jatomtype; - int btype,seed; - int imaxbond,jmaxbond; - int inewtype,jnewtype; - double cutsq,fraction; - - int createcount,createcounttotal; // bond formation stats - - int nmax; - int *bondcount; // count of created bonds this atom is part of - int *partner; // ID of preferred atom for this atom to bond to - double *distsq; // distance to preferred bond partner - double *probability; // random # to use in decision to form bond - - class RanMars *random; - class NeighList *list; - int countflag,commflag; - int nlevels_respa; -}; - -} - -#endif -#endif diff --git a/src/MOLECULE/fix_bond_swap.cpp b/src/MOLECULE/fix_bond_swap.cpp deleted file mode 100644 index daf9b13501..0000000000 --- a/src/MOLECULE/fix_bond_swap.cpp +++ /dev/null @@ -1,689 +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 "math.h" -#include "stdlib.h" -#include "string.h" -#include "fix_bond_swap.h" -#include "atom.h" -#include "force.h" -#include "pair.h" -#include "bond.h" -#include "angle.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "group.h" -#include "comm.h" -#include "domain.h" -#include "modify.h" -#include "compute.h" -#include "random_mars.h" -#include "memory.h" -#include "error.h" - -#include "update.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -FixBondSwap::FixBondSwap(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) -{ - if (narg != 6) error->all("Illegal fix bond/swap command"); - - vector_flag = 1; - size_vector = 2; - global_freq = 1; - extvector = 0; - - fraction = atof(arg[3]); - double cutoff = atof(arg[4]); - cutsq = cutoff*cutoff; - - // initialize Marsaglia RNG with processor-unique seed - - int seed = atoi(arg[5]); - random = new RanMars(lmp,seed + comm->me); - - // create a new compute temp style - // id = fix-ID + temp, compute group = fix group - - int n = strlen(id) + 6; - id_temp = new char[n]; - strcpy(id_temp,id); - strcat(id_temp,"_temp"); - - char **newarg = new char*[3]; - newarg[0] = id_temp; - newarg[1] = "all"; - newarg[2] = "temp"; - modify->add_compute(3,newarg); - delete [] newarg; - tflag = 1; - - // initialize atom list - - nmax = 0; - alist = NULL; - - naccept = foursome = 0; -} - -/* ---------------------------------------------------------------------- */ - -FixBondSwap::~FixBondSwap() -{ - delete random; - - // delete temperature if fix created it - - if (tflag) modify->delete_compute(id_temp); - delete [] id_temp; - - memory->destroy(alist); -} - -/* ---------------------------------------------------------------------- */ - -int FixBondSwap::setmask() -{ - int mask = 0; - mask |= PRE_NEIGHBOR; - return mask; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondSwap::init() -{ - // require an atom style with molecule IDs - - if (atom->molecule == NULL) - error->all("Must use atom style with molecule IDs with fix bond/swap"); - - int icompute = modify->find_compute(id_temp); - if (icompute < 0) - error->all("Temperature ID for fix bond/swap does not exist"); - temperature = modify->compute[icompute]; - - // pair and bonds must be defined - // no dihedral or improper potentials allowed - // special bonds must be 0 1 1 - - if (force->pair == NULL || force->bond == NULL) - error->all("Fix bond/swap requires pair and bond styles"); - - if (force->pair->single_enable == 0) - error->all("Pair style does not support fix bond/swap"); - - if (force->angle == NULL && atom->nangles > 0 && comm->me == 0) - error->warning("Fix bond/swap will ignore defined angles"); - - if (force->dihedral || force->improper) - error->all("Fix bond/swap cannot use dihedral or improper styles"); - - if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || - force->special_lj[3] != 1.0) - error->all("Fix bond/swap requires special_bonds = 0,1,1"); - - // need a half neighbor list, built when ever re-neighboring occurs - - int irequest = neighbor->request((void *) this); - neighbor->requests[irequest]->pair = 0; - neighbor->requests[irequest]->fix = 1; - - // zero out stats - - naccept = foursome = 0; - angleflag = 0; - if (force->angle) angleflag = 1; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondSwap::init_list(int id, NeighList *ptr) -{ - list = ptr; -} - -/* ---------------------------------------------------------------------- */ - -void FixBondSwap::pre_neighbor() -{ - int i,j,ii,jj,m,inum,jnum; - int inext,iprev,ilast,jnext,jprev,jlast,ibond,iangle,jbond,jangle; - int itag,inexttag,iprevtag,ilasttag,jtag,jnexttag,jprevtag,jlasttag; - int ibondtype,jbondtype,iangletype,inextangletype,jangletype,jnextangletype; - int i1,i2,i3,j1,j2,j3,tmp; - int *ilist,*jlist,*numneigh,**firstneigh; - double delta,factor; - - // compute current temp for Boltzmann factor test - - double t_current = temperature->compute_scalar(); - - // local ptrs to atom arrays - - int *tag = atom->tag; - int *mask = atom->mask; - int *molecule = atom->molecule; - int *num_bond = atom->num_bond; - int **bond_atom = atom->bond_atom; - int **bond_type = atom->bond_type; - int *num_angle = atom->num_angle; - int **angle_atom1 = atom->angle_atom1; - int **angle_atom2 = atom->angle_atom2; - int **angle_atom3 = atom->angle_atom3; - int **angle_type = atom->angle_type; - int **nspecial = atom->nspecial; - int **special = atom->special; - int newton_bond = force->newton_bond; - int nlocal = atom->nlocal; - - type = atom->type; - x = atom->x; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // randomize list of my owned atoms that are in fix group - // grow atom list if necessary - - if (nlocal > nmax) { - memory->destroy(alist); - nmax = atom->nmax; - memory->create(alist,nmax,"bondswap:alist"); - } - - int neligible = 0; - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - if (mask[i] & groupbit) - alist[neligible++] = i; - } - - for (i = 0; i < neligible; i++) { - j = static_cast (random->uniform() * neligible); - tmp = alist[i]; - alist[i] = alist[j]; - alist[j] = tmp; - } - - // examine ntest of my eligible atoms for potential swaps - // atom i is randomly selected via atom list - // look at all j neighbors of atom i - // atom j must be on-processor (j < nlocal) - // atom j must be in fix group - // i and j must be same distance from chain end (mol[i] = mol[j]) - // NOTE: must use extra parens in if test on mask[j] & groupbit - - int ntest = static_cast (fraction * neligible); - int accept = 0; - - for (int itest = 0; itest < ntest; itest++) { - i = alist[itest]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - if (j >= nlocal) continue; - if ((mask[j] & groupbit) == 0) continue; - if (molecule[i] != molecule[j]) continue; - - // look at all bond partners of atoms i and j - // use num_bond for this, not special list, so also find bondtypes - // inext,jnext = bonded atoms - // inext,jnext must be on-processor (inext,jnext < nlocal) - // inext,jnext must be same dist from chain end (mol[inext] = mol[jnext]) - // since swaps may occur between two ends of a single chain, insure - // the 4 atoms are unique (no duplicates): inext != jnext, inext != j - // all 4 old and new bonds must have length < cutoff - - for (ibond = 0; ibond < num_bond[i]; ibond++) { - inext = atom->map(bond_atom[i][ibond]); - if (inext >= nlocal || inext < 0) continue; - ibondtype = bond_type[i][ibond]; - - for (jbond = 0; jbond < num_bond[j]; jbond++) { - jnext = atom->map(bond_atom[j][jbond]); - if (jnext >= nlocal || jnext < 0) continue; - jbondtype = bond_type[j][jbond]; - - if (molecule[inext] != molecule[jnext]) continue; - if (inext == jnext || inext == j) continue; - if (dist_rsq(i,inext) >= cutsq) continue; - if (dist_rsq(j,jnext) >= cutsq) continue; - if (dist_rsq(i,jnext) >= cutsq) continue; - if (dist_rsq(j,inext) >= cutsq) continue; - - // if angles are enabled: - // find other atoms i,inext,j,jnext are in angles with - // and angletypes: i/j angletype, i/j nextangletype - // use num_angle for this, not special list, so also find angletypes - // 4 atoms consecutively along 1st chain: iprev,i,inext,ilast - // 4 atoms consecutively along 2nd chain: jprev,j,jnext,jlast - // prev or last atom can be non-existent at end of chain - // set prev/last = -1 in this case - // if newton bond = 0, then angles are stored by all 4 atoms - // so require that iprev,ilast,jprev,jlast be owned by this proc - // so all copies of angles can be updated if a swap takes place - - if (angleflag) { - itag = tag[i]; - inexttag = tag[inext]; - jtag = tag[j]; - jnexttag = tag[jnext]; - - iprev = -1; - for (iangle = 0; iangle < num_angle[i]; iangle++) { - i1 = angle_atom1[i][iangle]; - i2 = angle_atom2[i][iangle]; - i3 = angle_atom3[i][iangle]; - if (i2 == itag && i3 == inexttag) iprev = atom->map(i1); - else if (i1 == inexttag && i2 == itag) iprev = atom->map(i3); - if (iprev >= 0) { - iangletype = angle_type[i][iangle]; - break; - } - } - if (!newton_bond && iprev >= nlocal) continue; - - ilast = -1; - for (iangle = 0; iangle < num_angle[inext]; iangle++) { - i1 = angle_atom1[inext][iangle]; - i2 = angle_atom2[inext][iangle]; - i3 = angle_atom3[inext][iangle]; - if (i1 == itag && i2 == inexttag) ilast = atom->map(i3); - else if (i2 == inexttag && i3 == itag) ilast = atom->map(i1); - if (ilast >= 0) { - inextangletype = angle_type[inext][iangle]; - break; - } - } - if (!newton_bond && ilast >= nlocal) continue; - - jprev = -1; - for (jangle = 0; jangle < num_angle[j]; jangle++) { - j1 = angle_atom1[j][jangle]; - j2 = angle_atom2[j][jangle]; - j3 = angle_atom3[j][jangle]; - if (j2 == jtag && j3 == jnexttag) jprev = atom->map(j1); - else if (j1 == jnexttag && j2 == jtag) jprev = atom->map(j3); - if (jprev >= 0) { - jangletype = angle_type[j][jangle]; - break; - } - } - if (!newton_bond && jprev >= nlocal) continue; - - jlast = -1; - for (jangle = 0; jangle < num_angle[jnext]; jangle++) { - j1 = angle_atom1[jnext][jangle]; - j2 = angle_atom2[jnext][jangle]; - j3 = angle_atom3[jnext][jangle]; - if (j1 == jtag && j2 == jnexttag) jlast = atom->map(j3); - else if (j2 == jnexttag && j3 == jtag) jlast = atom->map(j1); - if (jlast >= 0) { - jnextangletype = angle_type[jnext][jangle]; - break; - } - } - if (!newton_bond && jlast >= nlocal) continue; - } - - // valid foursome found between 2 chains: - // chains = iprev-i-inext-ilast and jprev-j-jnext-jlast - // prev or last values are -1 if do not exist due to end of chain - // OK to call angle_eng with -1 atom, since just return 0.0 - // current energy of foursome = - // E_nb(i,j) + E_nb(i,jnext) + E_nb(inext,j) + E_nb(inext,jnext) + - // E_bond(i,inext) + E_bond(j,jnext) + - // E_angle(iprev,i,inext) + E_angle(i,inext,ilast) + - // E_angle(jprev,j,jnext) + E_angle(j,jnext,jlast) - // new energy of foursome with swapped bonds = - // E_nb(i,j) + E_nb(i,inext) + E_nb(j,jnext) + E_nb(inext,jnext) + - // E_bond(i,jnext) + E_bond(j,inext) + - // E_angle(iprev,i,jnext) + E_angle(i,jnext,jlast) + - // E_angle(jprev,j,inext) + E_angle(j,inext,ilast) - // energy delta = add/subtract differing terms between 2 formulas - - foursome++; - - delta = pair_eng(i,inext) + pair_eng(j,jnext) - - pair_eng(i,jnext) - pair_eng(inext,j); - delta += bond_eng(ibondtype,i,jnext) + bond_eng(jbondtype,j,inext) - - bond_eng(ibondtype,i,inext) - bond_eng(jbondtype,j,jnext); - if (angleflag) - delta += angle_eng(iangletype,iprev,i,jnext) + - angle_eng(jnextangletype,i,jnext,jlast) + - angle_eng(jangletype,jprev,j,inext) + - angle_eng(inextangletype,j,inext,ilast) - - angle_eng(iangletype,iprev,i,inext) - - angle_eng(inextangletype,i,inext,ilast) - - angle_eng(jangletype,jprev,j,jnext) - - angle_eng(jnextangletype,j,jnext,jlast); - - // if delta <= 0, accept swap - // if delta > 0, compute Boltzmann factor with current temperature - // only accept if greater than random value - // whether accept or not, exit test loop - - if (delta < 0.0) accept = 1; - else { - factor = exp(-delta/force->boltz/t_current); - if (random->uniform() < factor) accept = 1; - } - goto done; - } - } - } - } - - done: - if (!accept) return; - naccept++; - - // change bond partners of affected atoms - // on atom i: bond i-inext changes to i-jnext - // on atom j: bond j-jnext changes to j-inext - // on atom inext: bond inext-i changes to inext-j - // on atom jnext: bond jnext-j changes to jnext-i - - for (ibond = 0; ibond < num_bond[i]; ibond++) - if (bond_atom[i][ibond] == tag[inext]) bond_atom[i][ibond] = tag[jnext]; - for (jbond = 0; jbond < num_bond[j]; jbond++) - if (bond_atom[j][jbond] == tag[jnext]) bond_atom[j][jbond] = tag[inext]; - for (ibond = 0; ibond < num_bond[inext]; ibond++) - if (bond_atom[inext][ibond] == tag[i]) bond_atom[inext][ibond] = tag[j]; - for (jbond = 0; jbond < num_bond[jnext]; jbond++) - if (bond_atom[jnext][jbond] == tag[j]) bond_atom[jnext][jbond] = tag[i]; - - // set global tags of 4 atoms in bonds - - itag = tag[i]; - inexttag = tag[inext]; - - jtag = tag[j]; - jnexttag = tag[jnext]; - - // change 1st special neighbors of affected atoms: i,j,inext,jnext - // don't need to change 2nd/3rd special neighbors for any atom - // since special bonds = 0 1 1 means they are never used - - for (m = 0; m < nspecial[i][0]; m++) - if (special[i][m] == inexttag) special[i][m] = jnexttag; - for (m = 0; m < nspecial[j][0]; m++) - if (special[j][m] == jnexttag) special[j][m] = inexttag; - for (m = 0; m < nspecial[inext][0]; m++) - if (special[inext][m] == itag) special[inext][m] = jtag; - for (m = 0; m < nspecial[jnext][0]; m++) - if (special[jnext][m] == jtag) special[jnext][m] = itag; - - // done if no angles - - if (!angleflag) return; - - // set global tags of 4 additional atoms in angles, 0 if no angle - - if (iprev >= 0) iprevtag = tag[iprev]; - else iprevtag = 0; - if (ilast >= 0) ilasttag = tag[ilast]; - else ilasttag = 0; - - if (jprev >= 0) jprevtag = tag[jprev]; - else jprevtag = 0; - if (jlast >= 0) jlasttag = tag[jlast]; - else jlasttag = 0; - - // change angle partners of affected atoms - // must check if each angle is stored as a-b-c or c-b-a - // on atom i: - // angle iprev-i-inext changes to iprev-i-jnext - // angle i-inext-ilast changes to i-jnext-jlast - // on atom j: - // angle jprev-j-jnext changes to jprev-j-inext - // angle j-jnext-jlast changes to j-inext-ilast - // on atom inext: - // angle iprev-i-inext changes to jprev-j-inext - // angle i-inext-ilast changes to j-inext-ilast - // on atom jnext: - // angle jprev-j-jnext changes to iprev-i-jnext - // angle j-jnext-jlast changes to i-jnext-jlast - - for (iangle = 0; iangle < num_angle[i]; iangle++) { - i1 = angle_atom1[i][iangle]; - i2 = angle_atom2[i][iangle]; - i3 = angle_atom3[i][iangle]; - - if (i1 == iprevtag && i2 == itag && i3 == inexttag) - angle_atom3[i][iangle] = jnexttag; - else if (i1 == inexttag && i2 == itag && i3 == iprevtag) - angle_atom1[i][iangle] = jnexttag; - else if (i1 == itag && i2 == inexttag && i3 == ilasttag) { - angle_atom2[i][iangle] = jnexttag; - angle_atom3[i][iangle] = jlasttag; - } else if (i1 == ilasttag && i2 == inexttag && i3 == itag) { - angle_atom1[i][iangle] = jlasttag; - angle_atom2[i][iangle] = jnexttag; - } - } - - for (jangle = 0; jangle < num_angle[j]; jangle++) { - j1 = angle_atom1[j][jangle]; - j2 = angle_atom2[j][jangle]; - j3 = angle_atom3[j][jangle]; - - if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) - angle_atom3[j][jangle] = inexttag; - else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) - angle_atom1[j][jangle] = inexttag; - else if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) { - angle_atom2[j][jangle] = inexttag; - angle_atom3[j][jangle] = ilasttag; - } else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) { - angle_atom1[j][jangle] = ilasttag; - angle_atom2[j][jangle] = inexttag; - } - } - - for (iangle = 0; iangle < num_angle[inext]; iangle++) { - i1 = angle_atom1[inext][iangle]; - i2 = angle_atom2[inext][iangle]; - i3 = angle_atom3[inext][iangle]; - - if (i1 == iprevtag && i2 == itag && i3 == inexttag) { - angle_atom1[inext][iangle] = jprevtag; - angle_atom2[inext][iangle] = jtag; - } else if (i1 == inexttag && i2 == itag && i3 == iprevtag) { - angle_atom2[inext][iangle] = jtag; - angle_atom3[inext][iangle] = jprevtag; - } else if (i1 == itag && i2 == inexttag && i3 == ilasttag) - angle_atom1[inext][iangle] = jtag; - else if (i1 == ilasttag && i2 == inexttag && i3 == itag) - angle_atom3[inext][iangle] = jtag; - } - - for (jangle = 0; jangle < num_angle[jnext]; jangle++) { - j1 = angle_atom1[jnext][jangle]; - j2 = angle_atom2[jnext][jangle]; - j3 = angle_atom3[jnext][jangle]; - - if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) { - angle_atom1[jnext][jangle] = iprevtag; - angle_atom2[jnext][jangle] = itag; - } else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) { - angle_atom2[jnext][jangle] = itag; - angle_atom3[jnext][jangle] = iprevtag; - } else if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) - angle_atom1[jnext][jangle] = itag; - else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) - angle_atom3[jnext][jangle] = itag; - } - - // done if newton bond set - - if (newton_bond) return; - - // change angles stored by iprev,ilast,jprev,jlast - // on atom iprev: angle iprev-i-inext changes to iprev-i-jnext - // on atom jprev: angle jprev-j-jnext changes to jprev-j-inext - // on atom ilast: angle i-inext-ilast changes to j-inext-ilast - // on atom jlast: angle j-jnext-jlast changes to i-jnext-jlast - - for (iangle = 0; iangle < num_angle[iprev]; iangle++) { - i1 = angle_atom1[iprev][iangle]; - i2 = angle_atom2[iprev][iangle]; - i3 = angle_atom3[iprev][iangle]; - - if (i1 == iprevtag && i2 == itag && i3 == inexttag) - angle_atom3[iprev][iangle] = jnexttag; - else if (i1 == inexttag && i2 == itag && i3 == iprevtag) - angle_atom1[iprev][iangle] = jnexttag; - } - - for (jangle = 0; jangle < num_angle[jprev]; jangle++) { - j1 = angle_atom1[jprev][jangle]; - j2 = angle_atom2[jprev][jangle]; - j3 = angle_atom3[jprev][jangle]; - - if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) - angle_atom3[jprev][jangle] = inexttag; - else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) - angle_atom1[jprev][jangle] = inexttag; - } - - for (iangle = 0; iangle < num_angle[ilast]; iangle++) { - i1 = angle_atom1[ilast][iangle]; - i2 = angle_atom2[ilast][iangle]; - i3 = angle_atom3[ilast][iangle]; - - if (i1 == itag && i2 == inexttag && i3 == ilasttag) - angle_atom1[ilast][iangle] = jtag; - else if (i1 == ilasttag && i2 == inexttag && i3 == itag) - angle_atom3[ilast][iangle] = jtag; - } - - for (jangle = 0; jangle < num_angle[jlast]; jangle++) { - j1 = angle_atom1[jlast][jangle]; - j2 = angle_atom2[jlast][jangle]; - j3 = angle_atom3[jlast][jangle]; - - if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) - angle_atom1[jlast][jangle] = itag; - else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) - angle_atom3[jlast][jangle] = itag; - } -} - -/* ---------------------------------------------------------------------- */ - -int FixBondSwap::modify_param(int narg, char **arg) -{ - if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); - if (tflag) { - modify->delete_compute(id_temp); - tflag = 0; - } - delete [] id_temp; - int n = strlen(arg[1]) + 1; - id_temp = new char[n]; - strcpy(id_temp,arg[1]); - - int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); - temperature = modify->compute[icompute]; - - if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); - if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); - return 2; - } - return 0; -} - -/* ---------------------------------------------------------------------- - compute squared distance between atoms I,J - must use minimum_image since J was found thru atom->map() -------------------------------------------------------------------------- */ - -double FixBondSwap::dist_rsq(int i, int j) -{ - double delx = x[i][0] - x[j][0]; - double dely = x[i][1] - x[j][1]; - double delz = x[i][2] - x[j][2]; - domain->minimum_image(delx,dely,delz); - return (delx*delx + dely*dely + delz*delz); -} - -/* ---------------------------------------------------------------------- - return pairwise interaction energy between atoms I,J - will always be full non-bond interaction, so factors = 1 in single() call -------------------------------------------------------------------------- */ - -double FixBondSwap::pair_eng(int i, int j) -{ - double tmp; - double rsq = dist_rsq(i,j); - return force->pair->single(i,j,type[i],type[j],rsq,1.0,1.0,tmp); -} - -/* ---------------------------------------------------------------------- */ - -double FixBondSwap::bond_eng(int btype, int i, int j) -{ - double rsq = dist_rsq(i,j); - return force->bond->single(btype,rsq,i,j); -} - -/* ---------------------------------------------------------------------- */ - -double FixBondSwap::angle_eng(int atype, int i, int j, int k) -{ - // test for non-existent angle at end of chain - - if (i == -1 || k == -1) return 0.0; - return force->angle->single(atype,i,j,k); -} - -/* ---------------------------------------------------------------------- - return bond swapping stats - n = 1 is # of swaps - n = 2 is # of attempted swaps -------------------------------------------------------------------------- */ - -double FixBondSwap::compute_vector(int n) -{ - double one,all; - if (n == 0) one = naccept; - else one = foursome; - MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world); - return all; -} - -/* ---------------------------------------------------------------------- - memory usage of alist -------------------------------------------------------------------------- */ - -double FixBondSwap::memory_usage() -{ - double bytes = nmax * sizeof(int); - return bytes; -} diff --git a/src/MOLECULE/fix_bond_swap.h b/src/MOLECULE/fix_bond_swap.h deleted file mode 100644 index b8f991364a..0000000000 --- a/src/MOLECULE/fix_bond_swap.h +++ /dev/null @@ -1,63 +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. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(bond/swap,FixBondSwap) - -#else - -#ifndef LMP_FIX_BONDSWAP_H -#define LMP_FIX_BONDSWAP_H - -#include "fix.h" -#include "pair.h" - -namespace LAMMPS_NS { - -class FixBondSwap : public Fix { - public: - FixBondSwap(class LAMMPS *, int, char **); - ~FixBondSwap(); - int setmask(); - void init(); - void init_list(int, class NeighList *); - void pre_neighbor(); - int modify_param(int, char **); - double compute_vector(int); - double memory_usage(); - - private: - double fraction,cutsq; - int nmax,tflag; - int *alist; - int naccept,foursome; - int angleflag; - char *id_temp; - int *type; - double **x; - - class NeighList *list; - class Compute *temperature; - class RanMars *random; - - double dist_rsq(int, int); - double pair_eng(int, int); - double bond_eng(int, int, int); - double angle_eng(int, int, int, int); -}; - -} - -#endif -#endif From 9eb5aebed9772a25504f52ff3fdc4a2ef084b47f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:30:01 +0000 Subject: [PATCH 028/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6795 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/DSMC/Install.sh | 15 -- src/DSMC/pair_dsmc.cpp | 525 ----------------------------------------- src/DSMC/pair_dsmc.h | 109 --------- src/Makefile | 4 +- src/fix_restrain.cpp | 2 +- src/force.h | 1 + src/update.cpp | 6 + 7 files changed, 10 insertions(+), 652 deletions(-) delete mode 100644 src/DSMC/Install.sh delete mode 100644 src/DSMC/pair_dsmc.cpp delete mode 100644 src/DSMC/pair_dsmc.h diff --git a/src/DSMC/Install.sh b/src/DSMC/Install.sh deleted file mode 100644 index 60e34982ca..0000000000 --- a/src/DSMC/Install.sh +++ /dev/null @@ -1,15 +0,0 @@ -# Install/unInstall package files in LAMMPS - -if (test $1 = 1) then - - cp pair_dsmc.cpp .. - - cp pair_dsmc.h .. - -elif (test $1 = 0) then - - rm -f ../pair_dsmc.cpp - - rm -f ../pair_dsmc.h - -fi diff --git a/src/DSMC/pair_dsmc.cpp b/src/DSMC/pair_dsmc.cpp deleted file mode 100644 index b04dd8f6d7..0000000000 --- a/src/DSMC/pair_dsmc.cpp +++ /dev/null @@ -1,525 +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. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing authors: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_dsmc.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" -#include "domain.h" -#include "update.h" -#include "random_mars.h" -#include "limits.h" - -using namespace LAMMPS_NS; - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* ---------------------------------------------------------------------- */ - -PairDSMC::PairDSMC(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 0; - - total_number_of_collisions = 0; - max_particles = max_particle_list = 0; - next_particle = NULL; - random = NULL; -} - -/* ---------------------------------------------------------------------- */ - -PairDSMC::~PairDSMC() -{ - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - memory->destroy(sigma); - memory->destroy(cut); - memory->destroy(V_sigma_max); - memory->destroy(particle_list); - memory->destroy(first); - memory->destroy(number); - } - - delete [] next_particle; - delete random; -} - -/* ---------------------------------------------------------------------- */ - -void PairDSMC::compute(int eflag, int vflag) -{ - double **x = atom->x; - double *mass = atom->mass; - int *type = atom->type; - int nlocal = atom->nlocal; - - for (int i = 1; i <= atom->ntypes; ++i) - for (int j = 0; j < total_ncells; ++j) { - first[i][j] = -1; - number[i][j] = 0; - } - - if (atom->nmax > max_particles) { - delete [] next_particle; - max_particles = atom->nmax; - next_particle = new int[max_particles]; - } - - // find each particle's cell and sort by type - // assume a constant volume and shape simulation domain - // skip particle if outside processor domain - - for (int i = 0; i < nlocal; ++i) { - int xcell = static_cast((x[i][0] - domain->boxlo[0])/cellx); - int ycell = static_cast((x[i][1] - domain->boxlo[1])/celly); - int zcell = static_cast((x[i][2] - domain->boxlo[2])/cellz); - - if ((xcell < 0) or (xcell > ncellsx-1) or - (ycell < 0) or (ycell > ncellsy-1) or - (zcell < 0) or (zcell > ncellsz-1)) continue; - - int icell = xcell + ycell*ncellsx + zcell*ncellsx*ncellsy; - itype = type[i]; - next_particle[i] = first[itype][icell]; - first[itype][icell] = i; - number[itype][icell]++; - } - - for (int icell = 0; icell < total_ncells; ++icell) { - - for (itype = 1; itype <= atom->ntypes; ++itype) { - number_of_A = number[itype][icell]; - if (number_of_A > max_particle_list) { - max_particle_list = number_of_A; - memory->grow(particle_list,atom->ntypes+1,max_particle_list, - "pair:particle_list"); - } - - int m = first[itype][icell]; - for (int k = 0; k < number_of_A; k++) { - particle_list[itype][k] = m; - m = next_particle[m]; - } - } - - for (itype = 1; itype <= atom->ntypes; ++itype) { - imass = mass[itype]; - number_of_A = number[itype][icell]; - - for (jtype = itype; jtype <= atom->ntypes; ++jtype) { - jmass = mass[jtype]; - number_of_B = number[jtype][icell]; - - reduced_mass = imass*jmass/(imass + jmass); - total_mass = imass + jmass; - jmass_tmass = jmass/total_mass; - imass_tmass = imass/total_mass; - - // if necessary, recompute V_sigma_max values - - if (recompute_vsigmamax_stride && - (update->ntimestep % recompute_vsigmamax_stride == 0)) - recompute_V_sigma_max(icell); - - // # of collisions to perform for itype-jtype pairs - - double &Vs_max = V_sigma_max[itype][jtype]; - double num_of_collisions_double = number_of_A * number_of_B * - weighting * Vs_max * update->dt / vol; - - if ((itype == jtype) and number_of_B) - num_of_collisions_double *= - 0.5 * double(number_of_B - 1) / double(number_of_B); - - int num_of_collisions = - convert_double_to_equivalent_int(num_of_collisions_double); - - if (num_of_collisions > number_of_A) - error->warning("Pair dsmc: num_of_collisions > number_of_A",0); - if (num_of_collisions > number_of_B) - error->warning("Pair dsmc: num_of_collisions > number_of_B",0); - - // perform collisions on pairs of particles in icell - - for (int k = 0; k < num_of_collisions; k++) { - if ((number_of_A < 1) or (number_of_B < 1)) break; - int ith_A = static_cast(random->uniform()*number_of_A); - int jth_B = static_cast(random->uniform()*number_of_B); - int i = particle_list[itype][ith_A]; - int j = particle_list[jtype][jth_B]; - if (i == j) { - k--; - continue; - } - double probability = V_sigma(i,j)/Vs_max; - if (probability > random->uniform()) scatter_random(i,j,icell); - } - } - } - } -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairDSMC::allocate() -{ - allocated = 1; - int n = atom->ntypes; - - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; - - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(sigma,n+1,n+1,"pair:sigma"); - memory->create(V_sigma_max,n+1,n+1,"pair:V_sigma_max"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairDSMC::settings(int narg, char **arg) -{ - if (narg != 6) error->all("Illegal pair_style command"); - - cut_global = 0.0; - max_cell_size = force->numeric(arg[0]); - seed = force->inumeric(arg[1]); - weighting = force->numeric(arg[2]); - T_ref = force->numeric(arg[3]); - recompute_vsigmamax_stride = force->inumeric(arg[4]); - vsigmamax_samples = force->inumeric(arg[5]); - - // initialize Marsaglia RNG with processor-unique seed - - if (max_cell_size <= 0.0) error->all("Illegal pair_style command"); - if (seed <= 0) error->all("Illegal pair_style command"); - if (random) delete random; - random = new RanMars(lmp,seed + comm->me); - - kT_ref = force->boltz*T_ref; - - // 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 PairDSMC::coeff(int narg, char **arg) -{ - if (narg < 3 || narg > 4) 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 sigma_one = force->numeric(arg[2]); - - double cut_one = cut_global; - if (narg == 4) cut_one = force->numeric(arg[3]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - sigma[i][j] = sigma_one; - 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 PairDSMC::init_style() -{ - ncellsx = ncellsy = ncellsz = 1; - while (((domain->boxhi[0] - domain->boxlo[0])/ncellsx) > max_cell_size) - ncellsx++; - while (((domain->boxhi[1] - domain->boxlo[1])/ncellsy) > max_cell_size) - ncellsy++; - while (((domain->boxhi[2] - domain->boxlo[2])/ncellsz) > max_cell_size) - ncellsz++; - - cellx = (domain->boxhi[0] - domain->boxlo[0])/ncellsx; - celly = (domain->boxhi[1] - domain->boxlo[1])/ncellsy; - cellz = (domain->boxhi[2] - domain->boxlo[2])/ncellsz; - - if (comm->me == 0) { - if (screen) fprintf(screen,"DSMC cell size = %g x %g x %g\n", - cellx,celly,cellz); - if (logfile) fprintf(logfile,"DSMC cell size = %g x %g x %g\n", - cellx,celly,cellz); - } - - total_ncells = ncellsx*ncellsy*ncellsz; - vol = cellx*celly*cellz; - - memory->create(particle_list,atom->ntypes+1,0,"pair:particle_list"); - memory->create(first,atom->ntypes+1,total_ncells,"pair:first"); - memory->create(number,atom->ntypes+1,total_ncells,"pair:number"); - - for (int i = 1; i <= atom->ntypes; i++) - for (int j = 1; j <= atom->ntypes; j++) - V_sigma_max[i][j] = 0.0; - - two_pi = 8.0*atan(1.0); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairDSMC::init_one(int i, int j) -{ - if (setflag[i][j] == 0) cut[i][j] = 0.0; - return cut[i][j]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairDSMC::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(&sigma[i][j],sizeof(double),1,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairDSMC::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(&sigma[i][j],sizeof(double),1,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairDSMC::write_restart_settings(FILE *fp) -{ - fwrite(&cut_global,sizeof(double),1,fp); - fwrite(&max_cell_size,sizeof(double),1,fp); - fwrite(&seed,sizeof(int),1,fp); - fwrite(&offset_flag,sizeof(int),1,fp); - fwrite(&mix_flag,sizeof(int),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairDSMC::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_global,sizeof(double),1,fp); - fread(&max_cell_size,sizeof(double),1,fp); - fread(&seed,sizeof(int),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(&max_cell_size,1,MPI_DOUBLE,0,world); - MPI_Bcast(&seed,1,MPI_INT,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); - - // initialize Marsaglia RNG with processor-unique seed - // same seed that pair_style command initially specified - - if (random) delete random; - random = new RanMars(lmp,seed + comm->me); -} - -/*------------------------------------------------------------------------- - rezero and recompute the V_sigma_max values this timestep for use during - the next nrezero timesteps --------------------------------------------------------------------------*/ - -void PairDSMC::recompute_V_sigma_max(int icell) -{ - int i,j,k; - double Vsigma_max = 0; - - if (number_of_A && number_of_B) { - for (k = 0; k < vsigmamax_samples; k++) { - i = particle_list[itype] - [static_cast(random->uniform()*number_of_A)]; - j = particle_list[jtype] - [static_cast(random->uniform()*number_of_B)]; - if (i == j) continue; - Vsigma_max = MAX(Vsigma_max,V_sigma(i,j)); - } - } - V_sigma_max[itype][jtype] = Vsigma_max; -} - -/*------------------------------------------------------------------------- - VHS model - compute the velocity vector difference between i and j and multiply by - their combined collision cross section, sigma, for neutral-neutral - collisions using the Variable Hard Sphere model --------------------------------------------------------------------------*/ - -double PairDSMC::V_sigma(int i, int j) -{ - double relative_velocity_sq,relative_velocity,pair_sigma; - double delv[3]; - double *vi = atom->v[i]; - double *vj = atom->v[j]; - - subtract3d(vi,vj,delv); - relative_velocity_sq = dot3d(delv,delv); - relative_velocity = sqrt(relative_velocity_sq); - - // from Bird eq 4.63, and omega=0.67 - // (omega - 0.5) = 0.17 - // 1/GAMMA(2.5 - omega) = 1.06418029298371 - - if (relative_velocity_sq != 0.0) - pair_sigma = sigma[itype][jtype]* - pow(kT_ref/(0.5*reduced_mass*relative_velocity_sq),0.17) * - 1.06418029298371; - else - pair_sigma = 0.0; - - return relative_velocity*pair_sigma; -} - -/*------------------------------------------------------------------------- - generate new velocities for collided particles --------------------------------------------------------------------------*/ - -void PairDSMC::scatter_random(int i, int j, int icell) -{ - double mag_delv,cos_phi,cos_squared,r,theta; - double delv[3],vcm[3]; - double *vi = atom->v[i]; - double *vj = atom->v[j]; - - subtract3d(vi,vj,delv); - if (itype == jtype) mag_delv = sqrt(dot3d(delv,delv))*0.5; - else mag_delv = sqrt(dot3d(delv,delv)); - - cos_phi = 1.0 - (2.0*random->uniform()); - cos_squared = MIN(1.0,cos_phi*cos_phi); - r = sqrt(1.0 - cos_squared); - delv[0] = cos_phi*mag_delv; - theta = two_pi*random->uniform(); - delv[1] = r*mag_delv*cos(theta); - delv[2] = r*mag_delv*sin(theta); - - if (itype == jtype) { - vcm[0] = (vi[0]+vj[0])*0.5; - vcm[1] = (vi[1]+vj[1])*0.5; - vcm[2] = (vi[2]+vj[2])*0.5; - vi[0] = vcm[0] + delv[0]; - vi[1] = vcm[1] + delv[1]; - vi[2] = vcm[2] + delv[2]; - vj[0] = vcm[0] - delv[0]; - vj[1] = vcm[1] - delv[1]; - vj[2] = vcm[2] - delv[2]; - } else { - vcm[0] = vi[0]*imass_tmass + vj[0]*jmass_tmass; - vcm[1] = vi[1]*imass_tmass + vj[1]*jmass_tmass; - vcm[2] = vi[2]*imass_tmass + vj[2]*jmass_tmass; - vi[0] = vcm[0] + delv[0]*jmass_tmass; - vi[1] = vcm[1] + delv[1]*jmass_tmass; - vi[2] = vcm[2] + delv[2]*jmass_tmass; - vj[0] = vcm[0] - delv[0]*imass_tmass; - vj[1] = vcm[1] - delv[1]*imass_tmass; - vj[2] = vcm[2] - delv[2]*imass_tmass; - } - - total_number_of_collisions++; -} - -/* ---------------------------------------------------------------------- - This method converts the double supplied by the calling function into - an int, which is returned. By adding a random number between 0 and 1 - to the double before converting it to an int, we ensure that, - statistically, we round down with probability identical to the - remainder and up the rest of the time. So even though we're using an - integer, we're statistically matching the exact expression represented - by the double. -------------------------------------------------------------------------- */ - -int PairDSMC::convert_double_to_equivalent_int(double input_double) -{ - if (input_double > INT_MAX) - error->all("Tried to convert a double to int, but input_double > INT_MAX"); - - int output_int = static_cast(input_double + random->uniform()); - return output_int; -} diff --git a/src/DSMC/pair_dsmc.h b/src/DSMC/pair_dsmc.h deleted file mode 100644 index 7e2b784f73..0000000000 --- a/src/DSMC/pair_dsmc.h +++ /dev/null @@ -1,109 +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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(dsmc,PairDSMC) - -#else - -#ifndef LMP_PAIR_DSMC_H -#define LMP_PAIR_DSMC_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairDSMC : public Pair { - public: - PairDSMC(class LAMMPS *); - virtual ~PairDSMC(); - virtual void compute(int, int); - virtual void settings(int, char **); - void coeff(int, char **); - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - virtual void write_restart_settings(FILE *); - virtual void read_restart_settings(FILE *); - - private: - double cut_global; - double **cut; - double **sigma; - - double cellx; - double celly; - double cellz; - int ncellsx; - int ncellsy; - int ncellsz; - int total_ncells; - int total_number_of_collisions; - int recompute_vsigmamax_stride; - int vsigmamax_samples; - double T_ref; - double kT_ref; - double two_pi; - double max_cell_size; - - int seed; - int number_of_A; - int number_of_B; - int max_particle_list; - - class RanMars *random; - - int **particle_list; - int **first; - int **number; - - double **V_sigma_max; - - int max_particles; - int *next_particle; - - int itype; - int jtype; - - double imass; - double jmass; - double total_mass; - double reduced_mass; - double imass_tmass; - double jmass_tmass; - double vol; - double weighting; - - void allocate(); - void recompute_V_sigma_max(int); - double V_sigma(int, int); - void scatter_random(int, int, int); - int convert_double_to_equivalent_int(double); - - inline void subtract3d(const double *v1, const double *v2, double *v3) { - v3[0] = v2[0] - v1[0]; - v3[1] = v2[1] - v1[1]; - v3[2] = v2[2] - v1[2]; - } - - inline double dot3d(const double *v1, const double *v2) { - return( v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] ); - } -}; - -} - -#endif -#endif diff --git a/src/Makefile b/src/Makefile index 3bc766272f..d09c371239 100755 --- a/src/Makefile +++ b/src/Makefile @@ -13,8 +13,8 @@ OBJ = $(SRC:.cpp=.o) # Package variables -PACKAGE = asphere class2 colloid dipole dsmc gpu granular \ - kspace manybody meam molecule opt peri poems reax replica \ +PACKAGE = asphere class2 colloid dipole gpu granular \ + kspace manybody mc meam molecule opt peri poems reax replica \ shock srd xtc PACKUSER = user-misc user-atc user-awpmd user-cg-cmm \ diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp index a4e040f0c3..b9e16c7a41 100644 --- a/src/fix_restrain.cpp +++ b/src/fix_restrain.cpp @@ -288,7 +288,7 @@ void FixRestrain::restrain_dihedral() MPI_Comm_rank(world,&me); if (screen) { char str[128]; - sprintf(str,"Restrain problem: %d %d %d %d %d %d", + sprintf(str,"Restrain problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); error->warning(str); diff --git a/src/force.h b/src/force.h index df214c974f..fc1bd0a812 100644 --- a/src/force.h +++ b/src/force.h @@ -21,6 +21,7 @@ namespace LAMMPS_NS { class Force : protected Pointers { public: double boltz; // Boltzmann constant (eng/degree-K) + double hplanck; // Planck's constant (energy-time) double mvv2e; // conversion of mv^2 to energy double ftm2v; // conversion of ft/m to velocity double mv2d; // conversion of mass/volume to density diff --git a/src/update.cpp b/src/update.cpp index 3320ce9d8a..947bba8c1e 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -118,6 +118,7 @@ void Update::set_units(const char *style) if (strcmp(style,"lj") == 0) { force->boltz = 1.0; + force->hplanck = 0.18292026; // using LJ parameters for argon force->mvv2e = 1.0; force->ftm2v = 1.0; force->mv2d = 1.0; @@ -135,6 +136,7 @@ void Update::set_units(const char *style) } else if (strcmp(style,"real") == 0) { force->boltz = 0.0019872067; + force->hplanck = 95.306976368; force->mvv2e = 48.88821291 * 48.88821291; force->ftm2v = 1.0 / 48.88821291 / 48.88821291; force->mv2d = 1.0 / 0.602214179; @@ -152,6 +154,7 @@ void Update::set_units(const char *style) } else if (strcmp(style,"metal") == 0) { force->boltz = 8.617343e-5; + force->hplanck = 4.135667403e-3; force->mvv2e = 1.0364269e-4; force->ftm2v = 1.0 / 1.0364269e-4; force->mv2d = 1.0 / 0.602214179; @@ -169,6 +172,7 @@ void Update::set_units(const char *style) } else if (strcmp(style,"si") == 0) { force->boltz = 1.3806504e-23; + force->hplanck = 6.62606896e-34; force->mvv2e = 1.0; force->ftm2v = 1.0; force->mv2d = 1.0; @@ -186,6 +190,7 @@ void Update::set_units(const char *style) } else if (strcmp(style,"cgs") == 0) { force->boltz = 1.3806504e-16; + force->hplanck = 6.62606896e-27; force->mvv2e = 1.0; force->ftm2v = 1.0; force->mv2d = 1.0; @@ -203,6 +208,7 @@ void Update::set_units(const char *style) } else if (strcmp(style,"electron") == 0) { force->boltz = 3.16681534e-6; + force->hplanck = 0.1519829846; force->mvv2e = 1.06657236; force->ftm2v = 0.937582899; force->mv2d = 1.0; From 3a9ba7dd2837557de4b7363a2eafd59cf20082aa Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:30:15 +0000 Subject: [PATCH 029/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6796 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MC/Install.sh | 15 + src/MC/fix_bond_break.cpp | 392 +++++++++++++++++++++ src/MC/fix_bond_break.h | 60 ++++ src/MC/fix_bond_create.cpp | 617 +++++++++++++++++++++++++++++++++ src/MC/fix_bond_create.h | 74 ++++ src/MC/fix_bond_swap.cpp | 689 +++++++++++++++++++++++++++++++++++++ src/MC/fix_bond_swap.h | 63 ++++ src/MC/fix_gcmc.cpp | 562 ++++++++++++++++++++++++++++++ src/MC/fix_gcmc.h | 78 +++++ src/MC/pair_dsmc.cpp | 525 ++++++++++++++++++++++++++++ src/MC/pair_dsmc.h | 109 ++++++ 11 files changed, 3184 insertions(+) create mode 100644 src/MC/Install.sh create mode 100755 src/MC/fix_bond_break.cpp create mode 100755 src/MC/fix_bond_break.h create mode 100755 src/MC/fix_bond_create.cpp create mode 100755 src/MC/fix_bond_create.h create mode 100644 src/MC/fix_bond_swap.cpp create mode 100644 src/MC/fix_bond_swap.h create mode 100644 src/MC/fix_gcmc.cpp create mode 100644 src/MC/fix_gcmc.h create mode 100644 src/MC/pair_dsmc.cpp create mode 100644 src/MC/pair_dsmc.h diff --git a/src/MC/Install.sh b/src/MC/Install.sh new file mode 100644 index 0000000000..60e34982ca --- /dev/null +++ b/src/MC/Install.sh @@ -0,0 +1,15 @@ +# Install/unInstall package files in LAMMPS + +if (test $1 = 1) then + + cp pair_dsmc.cpp .. + + cp pair_dsmc.h .. + +elif (test $1 = 0) then + + rm -f ../pair_dsmc.cpp + + rm -f ../pair_dsmc.h + +fi diff --git a/src/MC/fix_bond_break.cpp b/src/MC/fix_bond_break.cpp new file mode 100755 index 0000000000..a4c44338da --- /dev/null +++ b/src/MC/fix_bond_break.cpp @@ -0,0 +1,392 @@ +/* ---------------------------------------------------------------------- + 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 "mpi.h" +#include "string.h" +#include "stdlib.h" +#include "fix_bond_break.h" +#include "update.h" +#include "respa.h" +#include "atom.h" +#include "force.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "random_mars.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) + +/* ---------------------------------------------------------------------- */ + +FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg < 6) error->all("Illegal fix bond/break command"); + + MPI_Comm_rank(world,&me); + + nevery = atoi(arg[3]); + if (nevery <= 0) error->all("Illegal fix bond/break command"); + + force_reneighbor = 1; + next_reneighbor = -1; + vector_flag = 1; + size_vector = 2; + global_freq = 1; + extvector = 0; + + btype = atoi(arg[4]); + double cutoff = atof(arg[5]); + + if (btype < 1 || btype > atom->nbondtypes) + error->all("Invalid bond type in fix bond/break command"); + if (cutoff < 0.0) error->all("Illegal fix bond/break command"); + + cutsq = cutoff*cutoff; + + // optional keywords + + fraction = 1.0; + int seed = 12345; + + int iarg = 6; + while (iarg < narg) { + if (strcmp(arg[iarg],"prob") == 0) { + if (iarg+3 > narg) error->all("Illegal fix bond/break command"); + fraction = atof(arg[iarg+1]); + seed = atoi(arg[iarg+2]); + if (fraction < 0.0 || fraction > 1.0) + error->all("Illegal fix bond/break command"); + if (seed <= 0) error->all("Illegal fix bond/break command"); + iarg += 3; + } else error->all("Illegal fix bond/break command"); + } + + // error check + + if (atom->molecular == 0) + error->all("Cannot use fix bond/break with non-molecular systems"); + + // initialize Marsaglia RNG with processor-unique seed + + random = new RanMars(lmp,seed + me); + + // set comm sizes needed by this fix + + comm_forward = 2; + comm_reverse = 2; + + // allocate arrays local to this fix + + nmax = 0; + partner = NULL; + distsq = NULL; + + // zero out stats + + breakcount = 0; + breakcounttotal = 0; +} + +/* ---------------------------------------------------------------------- */ + +FixBondBreak::~FixBondBreak() +{ + delete random; + + // delete locally stored arrays + + memory->destroy(partner); + memory->destroy(distsq); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondBreak::setmask() +{ + int mask = 0; + mask |= POST_INTEGRATE; + mask |= POST_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondBreak::init() +{ + // require special bonds = 0,1,1 + + int flag = 0; + if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || + force->special_lj[3] != 1.0) flag = 1; + if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || + force->special_coul[3] != 1.0) flag = 1; + if (flag) error->all("Fix bond/break requires special_bonds = 0,1,1"); + + // warn if angles, dihedrals, impropers are being used + + if (force->angle || force->dihedral || force->improper) { + if (me == 0) + error->warning("Broken bonds will not alter angles, " + "dihedrals, or impropers"); + } + + if (strstr(update->integrate_style,"respa")) + nlevels_respa = ((Respa *) update->integrate)->nlevels; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondBreak::post_integrate() +{ + int i,j,k,m,n,i1,i2,n1,n3,type; + double delx,dely,delz,rsq,min,max; + int *slist; + + if (update->ntimestep % nevery) return; + + // need updated ghost atom positions + + comm->forward_comm(); + + // resize bond partner list and initialize it + // probability array overlays distsq array + // needs to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(partner); + memory->destroy(distsq); + nmax = atom->nmax; + memory->create(partner,nmax,"bond/break:partner"); + memory->create(distsq,nmax,"bond/break:distsq"); + probability = distsq; + } + + int nlocal = atom->nlocal; + int nall = atom->nlocal + atom->nghost; + + for (i = 0; i < nall; i++) { + partner[i] = 0; + distsq[i] = 0.0; + } + + // loop over bond list + // setup possible partner list of bonds to break + + double **x = atom->x; + int *tag = atom->tag; + int *mask = atom->mask; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + + for (n = 0; n < nbondlist; n++) { + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + type = bondlist[n][2]; + if (!(mask[i1] & groupbit)) continue; + if (!(mask[i2] & groupbit)) continue; + if (type != btype) continue; + + delx = x[i1][0] - x[i2][0]; + dely = x[i1][1] - x[i2][1]; + delz = x[i1][2] - x[i2][2]; + domain->minimum_image(delx,dely,delz); + rsq = delx*delx + dely*dely + delz*delz; + if (rsq <= cutsq) continue; + + if (rsq > distsq[i1]) { + partner[i1] = tag[i2]; + distsq[i1] = rsq; + } + if (rsq > distsq[i2]) { + partner[i2] = tag[i1]; + distsq[i2] = rsq; + } + } + + // reverse comm of partner info + + if (force->newton_bond) comm->reverse_comm_fix(this); + + // each atom now knows its winning partner + // for prob check, generate random value for each atom with a bond partner + // forward comm of partner and random value, so ghosts have it + + if (fraction < 1.0) { + for (i = 0; i < nlocal; i++) + if (partner[i]) probability[i] = random->uniform(); + } + + comm->forward_comm_fix(this); + + // break bonds + // if both atoms list each other as winning bond partner + // and probability constraint is satisfied + + int **bond_type = atom->bond_type; + int **bond_atom = atom->bond_atom; + int *num_bond = atom->num_bond; + int **nspecial = atom->nspecial; + int **special = atom->special; + + int nbreak = 0; + for (i = 0; i < nlocal; i++) { + if (partner[i] == 0) continue; + j = atom->map(partner[i]); + if (partner[j] != tag[i]) continue; + + // apply probability constraint + // MIN,MAX insures values are added in same order on different procs + + if (fraction < 1.0) { + min = MIN(probability[i],probability[j]); + max = MAX(probability[i],probability[j]); + if (0.5*(min+max) >= fraction) continue; + } + + // delete bond from atom I if I stores it + // atom J will also do this + + for (m = 0; m < num_bond[i]; m++) { + if (bond_atom[i][m] == partner[i]) { + for (k = m; k < num_bond[i]-1; k++) { + bond_atom[i][k] = bond_atom[i][k+1]; + bond_type[i][k] = bond_type[i][k+1]; + } + num_bond[i]--; + break; + } + } + + // remove J from special bond list for atom I + // atom J will also do this + + slist = special[i]; + n1 = nspecial[i][0]; + n3 = nspecial[i][2]; + for (m = 0; m < n1; m++) + if (slist[m] == partner[i]) break; + for (; m < n3-1; m++) slist[m] = slist[m+1]; + nspecial[i][0]--; + nspecial[i][1]--; + nspecial[i][2]--; + + // count the broken bond once + + if (tag[i] < tag[j]) nbreak++; + } + + // tally stats + + MPI_Allreduce(&nbreak,&breakcount,1,MPI_INT,MPI_SUM,world); + breakcounttotal += breakcount; + atom->nbonds -= breakcount; + + // trigger reneighboring if any bonds were formed + + if (breakcount) next_reneighbor = update->ntimestep; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondBreak::post_integrate_respa(int ilevel, int iloop) +{ + if (ilevel == nlevels_respa-1) post_integrate(); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondBreak::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = partner[j]; + buf[m++] = probability[j]; + } + return 2; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondBreak::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + partner[i] = static_cast (buf[m++]); + probability[i] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int FixBondBreak::pack_reverse_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = partner[i]; + buf[m++] = distsq[i]; + } + return 2; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondBreak::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (buf[m+1] > distsq[j]) { + partner[j] = static_cast (buf[m++]); + distsq[j] = buf[m++]; + } else m += 2; + } +} + +/* ---------------------------------------------------------------------- */ + +double FixBondBreak::compute_vector(int n) +{ + if (n == 1) return (double) breakcount; + return (double) breakcounttotal; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double FixBondBreak::memory_usage() +{ + int nmax = atom->nmax; + double bytes = nmax * sizeof(int); + bytes += nmax * sizeof(double); + return bytes; +} diff --git a/src/MC/fix_bond_break.h b/src/MC/fix_bond_break.h new file mode 100755 index 0000000000..597a7e93f3 --- /dev/null +++ b/src/MC/fix_bond_break.h @@ -0,0 +1,60 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(bond/break,FixBondBreak) + +#else + +#ifndef LMP_FIX_BOND_BREAK_H +#define LMP_FIX_BOND_BREAK_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixBondBreak : public Fix { + public: + FixBondBreak(class LAMMPS *, int, char **); + ~FixBondBreak(); + int setmask(); + void init(); + void post_integrate(); + void post_integrate_respa(int,int); + + int pack_comm(int, int *, double *, int, int *); + void unpack_comm(int, int, double *); + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + double compute_vector(int); + double memory_usage(); + + private: + int me; + int btype,seed; + double cutsq,fraction; + + int breakcount,breakcounttotal; + int nmax; + int *partner; + double *distsq,*probability; + + class RanMars *random; + int nlevels_respa; +}; + +} + +#endif +#endif diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp new file mode 100755 index 0000000000..295f04981b --- /dev/null +++ b/src/MC/fix_bond_create.cpp @@ -0,0 +1,617 @@ +/* ---------------------------------------------------------------------- + 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 "mpi.h" +#include "string.h" +#include "stdlib.h" +#include "fix_bond_create.h" +#include "update.h" +#include "respa.h" +#include "atom.h" +#include "force.h" +#include "pair.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "random_mars.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define BIG 1.0e20 + +#define MIN(A,B) ((A) < (B)) ? (A) : (B) +#define MAX(A,B) ((A) > (B)) ? (A) : (B) + +/* ---------------------------------------------------------------------- */ + +FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg < 8) error->all("Illegal fix bond/create command"); + + MPI_Comm_rank(world,&me); + + nevery = atoi(arg[3]); + if (nevery <= 0) error->all("Illegal fix bond/create command"); + + force_reneighbor = 1; + next_reneighbor = -1; + vector_flag = 1; + size_vector = 2; + global_freq = 1; + extvector = 0; + + iatomtype = atoi(arg[4]); + jatomtype = atoi(arg[5]); + double cutoff = atof(arg[6]); + btype = atoi(arg[7]); + + if (iatomtype < 1 || iatomtype > atom->ntypes || + jatomtype < 1 || jatomtype > atom->ntypes) + error->all("Invalid atom type in fix bond/create command"); + if (cutoff < 0.0) error->all("Illegal fix bond/create command"); + if (btype < 1 || btype > atom->nbondtypes) + error->all("Invalid bond type in fix bond/create command"); + + cutsq = cutoff*cutoff; + + // optional keywords + + imaxbond = 0; + inewtype = iatomtype; + jmaxbond = 0; + jnewtype = jatomtype; + fraction = 1.0; + int seed = 12345; + + int iarg = 8; + while (iarg < narg) { + if (strcmp(arg[iarg],"iparam") == 0) { + if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + imaxbond = atoi(arg[iarg+1]); + inewtype = atoi(arg[iarg+2]); + if (imaxbond < 0) error->all("Illegal fix bond/create command"); + if (inewtype < 1 || inewtype > atom->ntypes) + error->all("Invalid atom type in fix bond/create command"); + iarg += 3; + } else if (strcmp(arg[iarg],"jparam") == 0) { + if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + jmaxbond = atoi(arg[iarg+1]); + jnewtype = atoi(arg[iarg+2]); + if (jmaxbond < 0) error->all("Illegal fix bond/create command"); + if (jnewtype < 1 || jnewtype > atom->ntypes) + error->all("Invalid atom type in fix bond/create command"); + iarg += 3; + } else if (strcmp(arg[iarg],"prob") == 0) { + if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + fraction = atof(arg[iarg+1]); + seed = atoi(arg[iarg+2]); + if (fraction < 0.0 || fraction > 1.0) + error->all("Illegal fix bond/create command"); + if (seed <= 0) error->all("Illegal fix bond/create command"); + iarg += 3; + } else error->all("Illegal fix bond/create command"); + } + + // error check + + if (atom->molecular == 0) + error->all("Cannot use fix bond/create with non-molecular systems"); + if (iatomtype == jatomtype && + ((imaxbond != jmaxbond) || (inewtype != jnewtype))) + error->all("Inconsistent iparam/jparam values in fix bond/create command"); + + // initialize Marsaglia RNG with processor-unique seed + + random = new RanMars(lmp,seed + me); + + // perform initial allocation of atom-based arrays + // register with Atom class + // bondcount values will be initialized in setup() + + bondcount = NULL; + grow_arrays(atom->nmax); + atom->add_callback(0); + countflag = 0; + + // set comm sizes needed by this fix + + comm_forward = 2; + comm_reverse = 2; + + // allocate arrays local to this fix + + nmax = 0; + partner = NULL; + distsq = NULL; + + // zero out stats + + createcount = 0; + createcounttotal = 0; +} + +/* ---------------------------------------------------------------------- */ + +FixBondCreate::~FixBondCreate() +{ + // unregister callbacks to this fix from Atom class + + atom->delete_callback(id,0); + + delete random; + + // delete locally stored arrays + + memory->destroy(bondcount); + memory->destroy(partner); + memory->destroy(distsq); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondCreate::setmask() +{ + int mask = 0; + mask |= POST_INTEGRATE; + mask |= POST_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::init() +{ + // check cutoff for iatomtype,jatomtype + + if (force->pair == NULL || cutsq > force->pair->cutsq[iatomtype][jatomtype]) + error->all("Fix bond/create cutoff is longer than pairwise cutoff"); + + // require special bonds = 0,1,1 + + if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || + force->special_lj[3] != 1.0) + error->all("Fix bond/create requires special_bonds lj = 0,1,1"); + + if (atom->q_flag) + if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || + force->special_coul[3] != 1.0) + error->all("Fix bond/create requires special_bonds coul = 0,1,1"); + + // warn if angles, dihedrals, impropers are being used + + if (force->angle || force->dihedral || force->improper) { + if (me == 0) + error->warning("Created bonds will not create angles, " + "dihedrals, or impropers"); + } + + // need a half neighbor list, built when ever re-neighboring occurs + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + + if (strstr(update->integrate_style,"respa")) + nlevels_respa = ((Respa *) update->integrate)->nlevels; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::setup(int vflag) +{ + int i,j,m; + + // compute initial bondcount if this is first run + // can't do this earlier, like in constructor or init, b/c need ghost info + + if (countflag) return; + countflag = 1; + + // count bonds stored with each bond I own + // if newton bond is not set, just increment count on atom I + // if newton bond is set, also increment count on atom J even if ghost + // bondcount is long enough to tally ghost atom counts + + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int **bond_atom = atom->bond_atom; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + int newton_bond = force->newton_bond; + + for (i = 0; i < nall; i++) bondcount[i] = 0; + + for (i = 0; i < nlocal; i++) + for (j = 0; j < num_bond[i]; j++) { + if (bond_type[i][j] == btype) { + bondcount[i]++; + if (newton_bond) { + m = atom->map(bond_atom[i][j]); + if (m < 0) + error->one("Could not count initial bonds in fix bond/create"); + bondcount[m]++; + } + } + } + + // if newton_bond is set, need to sum bondcount + + commflag = 0; + if (newton_bond) comm->reverse_comm_fix(this); +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::post_integrate() +{ + int i,j,m,ii,jj,inum,jnum,itype,jtype,n1,n3,possible; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq,min,max; + int *ilist,*jlist,*numneigh,**firstneigh,*slist; + + if (update->ntimestep % nevery) return; + + // need updated ghost atom positions + + comm->forward_comm(); + + // forward comm of bondcount, so ghosts have it + + commflag = 0; + comm->forward_comm_fix(this); + + // resize bond partner list and initialize it + // probability array overlays distsq array + // needs to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(partner); + memory->destroy(distsq); + nmax = atom->nmax; + memory->create(partner,nmax,"bond/create:partner"); + memory->create(distsq,nmax,"bond/create:distsq"); + probability = distsq; + } + + int nlocal = atom->nlocal; + int nall = atom->nlocal + atom->nghost; + + for (i = 0; i < nall; i++) { + partner[i] = 0; + distsq[i] = BIG; + } + + // loop over neighbors of my atoms + // each atom sets one closest eligible partner atom ID to bond with + + double **x = atom->x; + int *tag = atom->tag; + int *mask = atom->mask; + int *type = atom->type; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + if (!(mask[j] & groupbit)) continue; + jtype = type[j]; + + possible = 0; + if (itype == iatomtype && jtype == jatomtype) { + if ((imaxbond == 0 || bondcount[i] < imaxbond) && + (jmaxbond == 0 || bondcount[j] < jmaxbond)) + possible = 1; + } else if (itype == jatomtype && jtype == iatomtype) { + if ((jmaxbond == 0 || bondcount[i] < jmaxbond) && + (imaxbond == 0 || bondcount[j] < imaxbond)) + possible = 1; + } + if (!possible) 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 >= cutsq) continue; + + if (rsq < distsq[i]) { + partner[i] = tag[j]; + distsq[i] = rsq; + } + if (rsq < distsq[j]) { + partner[j] = tag[i]; + distsq[j] = rsq; + } + } + } + + // reverse comm of distsq and partner + // not needed if newton_pair off since I,J pair was seen by both procs + + commflag = 1; + if (force->newton_pair) comm->reverse_comm_fix(this); + + // each atom now knows its winning partner + // for prob check, generate random value for each atom with a bond partner + // forward comm of partner and random value, so ghosts have it + + if (fraction < 1.0) { + for (i = 0; i < nlocal; i++) + if (partner[i]) probability[i] = random->uniform(); + } + + commflag = 1; + comm->forward_comm_fix(this); + + // create bonds for atoms I own + // if other atom is owned by another proc, it should create same bond + // if both atoms list each other as winning bond partner + // and probability constraint is satisfied + + int **bond_type = atom->bond_type; + int **bond_atom = atom->bond_atom; + int *num_bond = atom->num_bond; + int **nspecial = atom->nspecial; + int **special = atom->special; + int newton_bond = force->newton_bond; + + int ncreate = 0; + for (i = 0; i < nlocal; i++) { + if (partner[i] == 0) continue; + j = atom->map(partner[i]); + if (partner[j] != tag[i]) continue; + + // apply probability constraint + // MIN,MAX insures values are added in same order on different procs + + if (fraction < 1.0) { + min = MIN(probability[i],probability[j]); + max = MAX(probability[i],probability[j]); + if (0.5*(min+max) >= fraction) continue; + } + + // if newton_bond is set, only store with I or J + // if not newton_bond, store bond with both I and J + + if (!newton_bond || tag[i] < tag[j]) { + if (num_bond[i] == atom->bond_per_atom) + error->one("New bond exceeded bonds per atom in fix bond/create"); + bond_type[i][num_bond[i]] = btype; + bond_atom[i][num_bond[i]] = tag[j]; + num_bond[i]++; + } + + // add a 1-2 neighbor to special bond list for atom I + // atom J will also do this + + slist = special[i]; + n1 = nspecial[i][0]; + n3 = nspecial[i][2]; + if (n3 == atom->maxspecial) + error->one("New bond exceeded special list size in fix bond/create"); + for (m = n3; m > n1; m--) slist[m+1] = slist[m]; + slist[n1] = tag[j]; + nspecial[i][0]++; + nspecial[i][1]++; + nspecial[i][2]++; + + // increment bondcount, convert atom to new type if limit reached + + bondcount[i]++; + if (type[i] == iatomtype) { + if (bondcount[i] == imaxbond) type[i] = inewtype; + } else { + if (bondcount[i] == jmaxbond) type[i] = jnewtype; + } + + // count the created bond once + + if (tag[i] < tag[j]) ncreate++; + } + + // tally stats + + MPI_Allreduce(&ncreate,&createcount,1,MPI_INT,MPI_SUM,world); + createcounttotal += createcount; + atom->nbonds += createcount; + + // trigger reneighboring if any bonds were formed + + if (createcount) next_reneighbor = update->ntimestep; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::post_integrate_respa(int ilevel, int iloop) +{ + if (ilevel == nlevels_respa-1) post_integrate(); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondCreate::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + + m = 0; + + if (commflag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = bondcount[j]; + } + return 1; + + } else { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = partner[j]; + buf[m++] = probability[j]; + } + return 2; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + + if (commflag == 0) { + for (i = first; i < last; i++) + bondcount[i] = static_cast (buf[m++]); + + } else { + for (i = first; i < last; i++) { + partner[i] = static_cast (buf[m++]); + probability[i] = buf[m++]; + } + } +} + +/* ---------------------------------------------------------------------- */ + +int FixBondCreate::pack_reverse_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + + if (commflag == 0) { + for (i = first; i < last; i++) + buf[m++] = bondcount[i]; + return 1; + + } else { + for (i = first; i < last; i++) { + buf[m++] = distsq[i]; + buf[m++] = partner[i]; + } + return 2; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixBondCreate::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + + if (commflag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + bondcount[j] += static_cast (buf[m++]); + } + + } else { + for (i = 0; i < n; i++) { + j = list[i]; + if (buf[m] < distsq[j]) { + distsq[j] = buf[m++]; + partner[j] = static_cast (buf[m++]); + } else m += 2; + } + } +} + +/* ---------------------------------------------------------------------- + allocate local atom-based arrays +------------------------------------------------------------------------- */ + +void FixBondCreate::grow_arrays(int nmax) +{ + memory->grow(bondcount,nmax,"bond/create:bondcount"); +} + +/* ---------------------------------------------------------------------- + copy values within local atom-based arrays +------------------------------------------------------------------------- */ + +void FixBondCreate::copy_arrays(int i, int j) +{ + bondcount[j] = bondcount[i]; +} + +/* ---------------------------------------------------------------------- + pack values in local atom-based arrays for exchange with another proc +------------------------------------------------------------------------- */ + +int FixBondCreate::pack_exchange(int i, double *buf) +{ + buf[0] = bondcount[i]; + return 1; +} + +/* ---------------------------------------------------------------------- + unpack values in local atom-based arrays from exchange with another proc +------------------------------------------------------------------------- */ + +int FixBondCreate::unpack_exchange(int nlocal, double *buf) +{ + bondcount[nlocal] = static_cast (buf[0]); + return 1; +} + +/* ---------------------------------------------------------------------- */ + +double FixBondCreate::compute_vector(int n) +{ + if (n == 1) return (double) createcount; + return (double) createcounttotal; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double FixBondCreate::memory_usage() +{ + int nmax = atom->nmax; + double bytes = nmax*2 * sizeof(int); + bytes += nmax * sizeof(double); + return bytes; +} diff --git a/src/MC/fix_bond_create.h b/src/MC/fix_bond_create.h new file mode 100755 index 0000000000..a54fd5d82a --- /dev/null +++ b/src/MC/fix_bond_create.h @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(bond/create,FixBondCreate) + +#else + +#ifndef LMP_FIX_BOND_CREATE_H +#define LMP_FIX_BOND_CREATE_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixBondCreate : public Fix { + public: + FixBondCreate(class LAMMPS *, int, char **); + ~FixBondCreate(); + int setmask(); + void init(); + void init_list(int, class NeighList *); + void setup(int); + void post_integrate(); + void post_integrate_respa(int, int); + + int pack_comm(int, int *, double *, int, int *); + void unpack_comm(int, int, double *); + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + void grow_arrays(int); + void copy_arrays(int, int); + int pack_exchange(int, double *); + int unpack_exchange(int, double *); + double compute_vector(int); + double memory_usage(); + + private: + int me; + int iatomtype,jatomtype; + int btype,seed; + int imaxbond,jmaxbond; + int inewtype,jnewtype; + double cutsq,fraction; + + int createcount,createcounttotal; // bond formation stats + + int nmax; + int *bondcount; // count of created bonds this atom is part of + int *partner; // ID of preferred atom for this atom to bond to + double *distsq; // distance to preferred bond partner + double *probability; // random # to use in decision to form bond + + class RanMars *random; + class NeighList *list; + int countflag,commflag; + int nlevels_respa; +}; + +} + +#endif +#endif diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp new file mode 100644 index 0000000000..daf9b13501 --- /dev/null +++ b/src/MC/fix_bond_swap.cpp @@ -0,0 +1,689 @@ +/* ---------------------------------------------------------------------- + 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 "stdlib.h" +#include "string.h" +#include "fix_bond_swap.h" +#include "atom.h" +#include "force.h" +#include "pair.h" +#include "bond.h" +#include "angle.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "group.h" +#include "comm.h" +#include "domain.h" +#include "modify.h" +#include "compute.h" +#include "random_mars.h" +#include "memory.h" +#include "error.h" + +#include "update.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixBondSwap::FixBondSwap(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg != 6) error->all("Illegal fix bond/swap command"); + + vector_flag = 1; + size_vector = 2; + global_freq = 1; + extvector = 0; + + fraction = atof(arg[3]); + double cutoff = atof(arg[4]); + cutsq = cutoff*cutoff; + + // initialize Marsaglia RNG with processor-unique seed + + int seed = atoi(arg[5]); + random = new RanMars(lmp,seed + comm->me); + + // create a new compute temp style + // id = fix-ID + temp, compute group = fix group + + int n = strlen(id) + 6; + id_temp = new char[n]; + strcpy(id_temp,id); + strcat(id_temp,"_temp"); + + char **newarg = new char*[3]; + newarg[0] = id_temp; + newarg[1] = "all"; + newarg[2] = "temp"; + modify->add_compute(3,newarg); + delete [] newarg; + tflag = 1; + + // initialize atom list + + nmax = 0; + alist = NULL; + + naccept = foursome = 0; +} + +/* ---------------------------------------------------------------------- */ + +FixBondSwap::~FixBondSwap() +{ + delete random; + + // delete temperature if fix created it + + if (tflag) modify->delete_compute(id_temp); + delete [] id_temp; + + memory->destroy(alist); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondSwap::setmask() +{ + int mask = 0; + mask |= PRE_NEIGHBOR; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondSwap::init() +{ + // require an atom style with molecule IDs + + if (atom->molecule == NULL) + error->all("Must use atom style with molecule IDs with fix bond/swap"); + + int icompute = modify->find_compute(id_temp); + if (icompute < 0) + error->all("Temperature ID for fix bond/swap does not exist"); + temperature = modify->compute[icompute]; + + // pair and bonds must be defined + // no dihedral or improper potentials allowed + // special bonds must be 0 1 1 + + if (force->pair == NULL || force->bond == NULL) + error->all("Fix bond/swap requires pair and bond styles"); + + if (force->pair->single_enable == 0) + error->all("Pair style does not support fix bond/swap"); + + if (force->angle == NULL && atom->nangles > 0 && comm->me == 0) + error->warning("Fix bond/swap will ignore defined angles"); + + if (force->dihedral || force->improper) + error->all("Fix bond/swap cannot use dihedral or improper styles"); + + if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || + force->special_lj[3] != 1.0) + error->all("Fix bond/swap requires special_bonds = 0,1,1"); + + // need a half neighbor list, built when ever re-neighboring occurs + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + + // zero out stats + + naccept = foursome = 0; + angleflag = 0; + if (force->angle) angleflag = 1; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondSwap::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondSwap::pre_neighbor() +{ + int i,j,ii,jj,m,inum,jnum; + int inext,iprev,ilast,jnext,jprev,jlast,ibond,iangle,jbond,jangle; + int itag,inexttag,iprevtag,ilasttag,jtag,jnexttag,jprevtag,jlasttag; + int ibondtype,jbondtype,iangletype,inextangletype,jangletype,jnextangletype; + int i1,i2,i3,j1,j2,j3,tmp; + int *ilist,*jlist,*numneigh,**firstneigh; + double delta,factor; + + // compute current temp for Boltzmann factor test + + double t_current = temperature->compute_scalar(); + + // local ptrs to atom arrays + + int *tag = atom->tag; + int *mask = atom->mask; + int *molecule = atom->molecule; + int *num_bond = atom->num_bond; + int **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *num_angle = atom->num_angle; + int **angle_atom1 = atom->angle_atom1; + int **angle_atom2 = atom->angle_atom2; + int **angle_atom3 = atom->angle_atom3; + int **angle_type = atom->angle_type; + int **nspecial = atom->nspecial; + int **special = atom->special; + int newton_bond = force->newton_bond; + int nlocal = atom->nlocal; + + type = atom->type; + x = atom->x; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // randomize list of my owned atoms that are in fix group + // grow atom list if necessary + + if (nlocal > nmax) { + memory->destroy(alist); + nmax = atom->nmax; + memory->create(alist,nmax,"bondswap:alist"); + } + + int neligible = 0; + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (mask[i] & groupbit) + alist[neligible++] = i; + } + + for (i = 0; i < neligible; i++) { + j = static_cast (random->uniform() * neligible); + tmp = alist[i]; + alist[i] = alist[j]; + alist[j] = tmp; + } + + // examine ntest of my eligible atoms for potential swaps + // atom i is randomly selected via atom list + // look at all j neighbors of atom i + // atom j must be on-processor (j < nlocal) + // atom j must be in fix group + // i and j must be same distance from chain end (mol[i] = mol[j]) + // NOTE: must use extra parens in if test on mask[j] & groupbit + + int ntest = static_cast (fraction * neligible); + int accept = 0; + + for (int itest = 0; itest < ntest; itest++) { + i = alist[itest]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + if (j >= nlocal) continue; + if ((mask[j] & groupbit) == 0) continue; + if (molecule[i] != molecule[j]) continue; + + // look at all bond partners of atoms i and j + // use num_bond for this, not special list, so also find bondtypes + // inext,jnext = bonded atoms + // inext,jnext must be on-processor (inext,jnext < nlocal) + // inext,jnext must be same dist from chain end (mol[inext] = mol[jnext]) + // since swaps may occur between two ends of a single chain, insure + // the 4 atoms are unique (no duplicates): inext != jnext, inext != j + // all 4 old and new bonds must have length < cutoff + + for (ibond = 0; ibond < num_bond[i]; ibond++) { + inext = atom->map(bond_atom[i][ibond]); + if (inext >= nlocal || inext < 0) continue; + ibondtype = bond_type[i][ibond]; + + for (jbond = 0; jbond < num_bond[j]; jbond++) { + jnext = atom->map(bond_atom[j][jbond]); + if (jnext >= nlocal || jnext < 0) continue; + jbondtype = bond_type[j][jbond]; + + if (molecule[inext] != molecule[jnext]) continue; + if (inext == jnext || inext == j) continue; + if (dist_rsq(i,inext) >= cutsq) continue; + if (dist_rsq(j,jnext) >= cutsq) continue; + if (dist_rsq(i,jnext) >= cutsq) continue; + if (dist_rsq(j,inext) >= cutsq) continue; + + // if angles are enabled: + // find other atoms i,inext,j,jnext are in angles with + // and angletypes: i/j angletype, i/j nextangletype + // use num_angle for this, not special list, so also find angletypes + // 4 atoms consecutively along 1st chain: iprev,i,inext,ilast + // 4 atoms consecutively along 2nd chain: jprev,j,jnext,jlast + // prev or last atom can be non-existent at end of chain + // set prev/last = -1 in this case + // if newton bond = 0, then angles are stored by all 4 atoms + // so require that iprev,ilast,jprev,jlast be owned by this proc + // so all copies of angles can be updated if a swap takes place + + if (angleflag) { + itag = tag[i]; + inexttag = tag[inext]; + jtag = tag[j]; + jnexttag = tag[jnext]; + + iprev = -1; + for (iangle = 0; iangle < num_angle[i]; iangle++) { + i1 = angle_atom1[i][iangle]; + i2 = angle_atom2[i][iangle]; + i3 = angle_atom3[i][iangle]; + if (i2 == itag && i3 == inexttag) iprev = atom->map(i1); + else if (i1 == inexttag && i2 == itag) iprev = atom->map(i3); + if (iprev >= 0) { + iangletype = angle_type[i][iangle]; + break; + } + } + if (!newton_bond && iprev >= nlocal) continue; + + ilast = -1; + for (iangle = 0; iangle < num_angle[inext]; iangle++) { + i1 = angle_atom1[inext][iangle]; + i2 = angle_atom2[inext][iangle]; + i3 = angle_atom3[inext][iangle]; + if (i1 == itag && i2 == inexttag) ilast = atom->map(i3); + else if (i2 == inexttag && i3 == itag) ilast = atom->map(i1); + if (ilast >= 0) { + inextangletype = angle_type[inext][iangle]; + break; + } + } + if (!newton_bond && ilast >= nlocal) continue; + + jprev = -1; + for (jangle = 0; jangle < num_angle[j]; jangle++) { + j1 = angle_atom1[j][jangle]; + j2 = angle_atom2[j][jangle]; + j3 = angle_atom3[j][jangle]; + if (j2 == jtag && j3 == jnexttag) jprev = atom->map(j1); + else if (j1 == jnexttag && j2 == jtag) jprev = atom->map(j3); + if (jprev >= 0) { + jangletype = angle_type[j][jangle]; + break; + } + } + if (!newton_bond && jprev >= nlocal) continue; + + jlast = -1; + for (jangle = 0; jangle < num_angle[jnext]; jangle++) { + j1 = angle_atom1[jnext][jangle]; + j2 = angle_atom2[jnext][jangle]; + j3 = angle_atom3[jnext][jangle]; + if (j1 == jtag && j2 == jnexttag) jlast = atom->map(j3); + else if (j2 == jnexttag && j3 == jtag) jlast = atom->map(j1); + if (jlast >= 0) { + jnextangletype = angle_type[jnext][jangle]; + break; + } + } + if (!newton_bond && jlast >= nlocal) continue; + } + + // valid foursome found between 2 chains: + // chains = iprev-i-inext-ilast and jprev-j-jnext-jlast + // prev or last values are -1 if do not exist due to end of chain + // OK to call angle_eng with -1 atom, since just return 0.0 + // current energy of foursome = + // E_nb(i,j) + E_nb(i,jnext) + E_nb(inext,j) + E_nb(inext,jnext) + + // E_bond(i,inext) + E_bond(j,jnext) + + // E_angle(iprev,i,inext) + E_angle(i,inext,ilast) + + // E_angle(jprev,j,jnext) + E_angle(j,jnext,jlast) + // new energy of foursome with swapped bonds = + // E_nb(i,j) + E_nb(i,inext) + E_nb(j,jnext) + E_nb(inext,jnext) + + // E_bond(i,jnext) + E_bond(j,inext) + + // E_angle(iprev,i,jnext) + E_angle(i,jnext,jlast) + + // E_angle(jprev,j,inext) + E_angle(j,inext,ilast) + // energy delta = add/subtract differing terms between 2 formulas + + foursome++; + + delta = pair_eng(i,inext) + pair_eng(j,jnext) - + pair_eng(i,jnext) - pair_eng(inext,j); + delta += bond_eng(ibondtype,i,jnext) + bond_eng(jbondtype,j,inext) - + bond_eng(ibondtype,i,inext) - bond_eng(jbondtype,j,jnext); + if (angleflag) + delta += angle_eng(iangletype,iprev,i,jnext) + + angle_eng(jnextangletype,i,jnext,jlast) + + angle_eng(jangletype,jprev,j,inext) + + angle_eng(inextangletype,j,inext,ilast) - + angle_eng(iangletype,iprev,i,inext) - + angle_eng(inextangletype,i,inext,ilast) - + angle_eng(jangletype,jprev,j,jnext) - + angle_eng(jnextangletype,j,jnext,jlast); + + // if delta <= 0, accept swap + // if delta > 0, compute Boltzmann factor with current temperature + // only accept if greater than random value + // whether accept or not, exit test loop + + if (delta < 0.0) accept = 1; + else { + factor = exp(-delta/force->boltz/t_current); + if (random->uniform() < factor) accept = 1; + } + goto done; + } + } + } + } + + done: + if (!accept) return; + naccept++; + + // change bond partners of affected atoms + // on atom i: bond i-inext changes to i-jnext + // on atom j: bond j-jnext changes to j-inext + // on atom inext: bond inext-i changes to inext-j + // on atom jnext: bond jnext-j changes to jnext-i + + for (ibond = 0; ibond < num_bond[i]; ibond++) + if (bond_atom[i][ibond] == tag[inext]) bond_atom[i][ibond] = tag[jnext]; + for (jbond = 0; jbond < num_bond[j]; jbond++) + if (bond_atom[j][jbond] == tag[jnext]) bond_atom[j][jbond] = tag[inext]; + for (ibond = 0; ibond < num_bond[inext]; ibond++) + if (bond_atom[inext][ibond] == tag[i]) bond_atom[inext][ibond] = tag[j]; + for (jbond = 0; jbond < num_bond[jnext]; jbond++) + if (bond_atom[jnext][jbond] == tag[j]) bond_atom[jnext][jbond] = tag[i]; + + // set global tags of 4 atoms in bonds + + itag = tag[i]; + inexttag = tag[inext]; + + jtag = tag[j]; + jnexttag = tag[jnext]; + + // change 1st special neighbors of affected atoms: i,j,inext,jnext + // don't need to change 2nd/3rd special neighbors for any atom + // since special bonds = 0 1 1 means they are never used + + for (m = 0; m < nspecial[i][0]; m++) + if (special[i][m] == inexttag) special[i][m] = jnexttag; + for (m = 0; m < nspecial[j][0]; m++) + if (special[j][m] == jnexttag) special[j][m] = inexttag; + for (m = 0; m < nspecial[inext][0]; m++) + if (special[inext][m] == itag) special[inext][m] = jtag; + for (m = 0; m < nspecial[jnext][0]; m++) + if (special[jnext][m] == jtag) special[jnext][m] = itag; + + // done if no angles + + if (!angleflag) return; + + // set global tags of 4 additional atoms in angles, 0 if no angle + + if (iprev >= 0) iprevtag = tag[iprev]; + else iprevtag = 0; + if (ilast >= 0) ilasttag = tag[ilast]; + else ilasttag = 0; + + if (jprev >= 0) jprevtag = tag[jprev]; + else jprevtag = 0; + if (jlast >= 0) jlasttag = tag[jlast]; + else jlasttag = 0; + + // change angle partners of affected atoms + // must check if each angle is stored as a-b-c or c-b-a + // on atom i: + // angle iprev-i-inext changes to iprev-i-jnext + // angle i-inext-ilast changes to i-jnext-jlast + // on atom j: + // angle jprev-j-jnext changes to jprev-j-inext + // angle j-jnext-jlast changes to j-inext-ilast + // on atom inext: + // angle iprev-i-inext changes to jprev-j-inext + // angle i-inext-ilast changes to j-inext-ilast + // on atom jnext: + // angle jprev-j-jnext changes to iprev-i-jnext + // angle j-jnext-jlast changes to i-jnext-jlast + + for (iangle = 0; iangle < num_angle[i]; iangle++) { + i1 = angle_atom1[i][iangle]; + i2 = angle_atom2[i][iangle]; + i3 = angle_atom3[i][iangle]; + + if (i1 == iprevtag && i2 == itag && i3 == inexttag) + angle_atom3[i][iangle] = jnexttag; + else if (i1 == inexttag && i2 == itag && i3 == iprevtag) + angle_atom1[i][iangle] = jnexttag; + else if (i1 == itag && i2 == inexttag && i3 == ilasttag) { + angle_atom2[i][iangle] = jnexttag; + angle_atom3[i][iangle] = jlasttag; + } else if (i1 == ilasttag && i2 == inexttag && i3 == itag) { + angle_atom1[i][iangle] = jlasttag; + angle_atom2[i][iangle] = jnexttag; + } + } + + for (jangle = 0; jangle < num_angle[j]; jangle++) { + j1 = angle_atom1[j][jangle]; + j2 = angle_atom2[j][jangle]; + j3 = angle_atom3[j][jangle]; + + if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) + angle_atom3[j][jangle] = inexttag; + else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) + angle_atom1[j][jangle] = inexttag; + else if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) { + angle_atom2[j][jangle] = inexttag; + angle_atom3[j][jangle] = ilasttag; + } else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) { + angle_atom1[j][jangle] = ilasttag; + angle_atom2[j][jangle] = inexttag; + } + } + + for (iangle = 0; iangle < num_angle[inext]; iangle++) { + i1 = angle_atom1[inext][iangle]; + i2 = angle_atom2[inext][iangle]; + i3 = angle_atom3[inext][iangle]; + + if (i1 == iprevtag && i2 == itag && i3 == inexttag) { + angle_atom1[inext][iangle] = jprevtag; + angle_atom2[inext][iangle] = jtag; + } else if (i1 == inexttag && i2 == itag && i3 == iprevtag) { + angle_atom2[inext][iangle] = jtag; + angle_atom3[inext][iangle] = jprevtag; + } else if (i1 == itag && i2 == inexttag && i3 == ilasttag) + angle_atom1[inext][iangle] = jtag; + else if (i1 == ilasttag && i2 == inexttag && i3 == itag) + angle_atom3[inext][iangle] = jtag; + } + + for (jangle = 0; jangle < num_angle[jnext]; jangle++) { + j1 = angle_atom1[jnext][jangle]; + j2 = angle_atom2[jnext][jangle]; + j3 = angle_atom3[jnext][jangle]; + + if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) { + angle_atom1[jnext][jangle] = iprevtag; + angle_atom2[jnext][jangle] = itag; + } else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) { + angle_atom2[jnext][jangle] = itag; + angle_atom3[jnext][jangle] = iprevtag; + } else if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) + angle_atom1[jnext][jangle] = itag; + else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) + angle_atom3[jnext][jangle] = itag; + } + + // done if newton bond set + + if (newton_bond) return; + + // change angles stored by iprev,ilast,jprev,jlast + // on atom iprev: angle iprev-i-inext changes to iprev-i-jnext + // on atom jprev: angle jprev-j-jnext changes to jprev-j-inext + // on atom ilast: angle i-inext-ilast changes to j-inext-ilast + // on atom jlast: angle j-jnext-jlast changes to i-jnext-jlast + + for (iangle = 0; iangle < num_angle[iprev]; iangle++) { + i1 = angle_atom1[iprev][iangle]; + i2 = angle_atom2[iprev][iangle]; + i3 = angle_atom3[iprev][iangle]; + + if (i1 == iprevtag && i2 == itag && i3 == inexttag) + angle_atom3[iprev][iangle] = jnexttag; + else if (i1 == inexttag && i2 == itag && i3 == iprevtag) + angle_atom1[iprev][iangle] = jnexttag; + } + + for (jangle = 0; jangle < num_angle[jprev]; jangle++) { + j1 = angle_atom1[jprev][jangle]; + j2 = angle_atom2[jprev][jangle]; + j3 = angle_atom3[jprev][jangle]; + + if (j1 == jprevtag && j2 == jtag && j3 == jnexttag) + angle_atom3[jprev][jangle] = inexttag; + else if (j1 == jnexttag && j2 == jtag && j3 == jprevtag) + angle_atom1[jprev][jangle] = inexttag; + } + + for (iangle = 0; iangle < num_angle[ilast]; iangle++) { + i1 = angle_atom1[ilast][iangle]; + i2 = angle_atom2[ilast][iangle]; + i3 = angle_atom3[ilast][iangle]; + + if (i1 == itag && i2 == inexttag && i3 == ilasttag) + angle_atom1[ilast][iangle] = jtag; + else if (i1 == ilasttag && i2 == inexttag && i3 == itag) + angle_atom3[ilast][iangle] = jtag; + } + + for (jangle = 0; jangle < num_angle[jlast]; jangle++) { + j1 = angle_atom1[jlast][jangle]; + j2 = angle_atom2[jlast][jangle]; + j3 = angle_atom3[jlast][jangle]; + + if (j1 == jtag && j2 == jnexttag && j3 == jlasttag) + angle_atom1[jlast][jangle] = itag; + else if (j1 == jlasttag && j2 == jnexttag && j3 == jtag) + angle_atom3[jlast][jangle] = itag; + } +} + +/* ---------------------------------------------------------------------- */ + +int FixBondSwap::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0],"temp") == 0) { + if (narg < 2) error->all("Illegal fix_modify command"); + if (tflag) { + modify->delete_compute(id_temp); + tflag = 0; + } + delete [] id_temp; + int n = strlen(arg[1]) + 1; + id_temp = new char[n]; + strcpy(id_temp,arg[1]); + + int icompute = modify->find_compute(id_temp); + if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + temperature = modify->compute[icompute]; + + if (temperature->tempflag == 0) + error->all("Fix_modify temperature ID does not compute temperature"); + if (temperature->igroup != igroup && comm->me == 0) + error->warning("Group for fix_modify temp != fix group"); + return 2; + } + return 0; +} + +/* ---------------------------------------------------------------------- + compute squared distance between atoms I,J + must use minimum_image since J was found thru atom->map() +------------------------------------------------------------------------- */ + +double FixBondSwap::dist_rsq(int i, int j) +{ + double delx = x[i][0] - x[j][0]; + double dely = x[i][1] - x[j][1]; + double delz = x[i][2] - x[j][2]; + domain->minimum_image(delx,dely,delz); + return (delx*delx + dely*dely + delz*delz); +} + +/* ---------------------------------------------------------------------- + return pairwise interaction energy between atoms I,J + will always be full non-bond interaction, so factors = 1 in single() call +------------------------------------------------------------------------- */ + +double FixBondSwap::pair_eng(int i, int j) +{ + double tmp; + double rsq = dist_rsq(i,j); + return force->pair->single(i,j,type[i],type[j],rsq,1.0,1.0,tmp); +} + +/* ---------------------------------------------------------------------- */ + +double FixBondSwap::bond_eng(int btype, int i, int j) +{ + double rsq = dist_rsq(i,j); + return force->bond->single(btype,rsq,i,j); +} + +/* ---------------------------------------------------------------------- */ + +double FixBondSwap::angle_eng(int atype, int i, int j, int k) +{ + // test for non-existent angle at end of chain + + if (i == -1 || k == -1) return 0.0; + return force->angle->single(atype,i,j,k); +} + +/* ---------------------------------------------------------------------- + return bond swapping stats + n = 1 is # of swaps + n = 2 is # of attempted swaps +------------------------------------------------------------------------- */ + +double FixBondSwap::compute_vector(int n) +{ + double one,all; + if (n == 0) one = naccept; + else one = foursome; + MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world); + return all; +} + +/* ---------------------------------------------------------------------- + memory usage of alist +------------------------------------------------------------------------- */ + +double FixBondSwap::memory_usage() +{ + double bytes = nmax * sizeof(int); + return bytes; +} diff --git a/src/MC/fix_bond_swap.h b/src/MC/fix_bond_swap.h new file mode 100644 index 0000000000..b8f991364a --- /dev/null +++ b/src/MC/fix_bond_swap.h @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(bond/swap,FixBondSwap) + +#else + +#ifndef LMP_FIX_BONDSWAP_H +#define LMP_FIX_BONDSWAP_H + +#include "fix.h" +#include "pair.h" + +namespace LAMMPS_NS { + +class FixBondSwap : public Fix { + public: + FixBondSwap(class LAMMPS *, int, char **); + ~FixBondSwap(); + int setmask(); + void init(); + void init_list(int, class NeighList *); + void pre_neighbor(); + int modify_param(int, char **); + double compute_vector(int); + double memory_usage(); + + private: + double fraction,cutsq; + int nmax,tflag; + int *alist; + int naccept,foursome; + int angleflag; + char *id_temp; + int *type; + double **x; + + class NeighList *list; + class Compute *temperature; + class RanMars *random; + + double dist_rsq(int, int); + double pair_eng(int, int); + double bond_eng(int, int, int); + double angle_eng(int, int, int, int); +}; + +} + +#endif +#endif diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp new file mode 100644 index 0000000000..9f3dfc5e82 --- /dev/null +++ b/src/MC/fix_gcmc.cpp @@ -0,0 +1,562 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "fix_gcmc.h" +#include "atom.h" +#include "atom_vec.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "comm.h" +#include "group.h" +#include "domain.h" +#include "random_park.h" +#include "force.h" +#include "pair.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg < 11) error->all("Illegal fix GCMC command"); + + vector_flag = 1; + size_vector = 6; + global_freq = 1; + extvector = 0; + restart_global = 1; + time_depend = 1; + + // required args + + nevery = atoi(arg[3]); + nexchanges = atoi(arg[4]); + nmcmoves = atoi(arg[5]); + ntype = atoi(arg[6]); + seed = atoi(arg[7]); + reservoir_temperature = atof(arg[8]); + chemical_potential = atof(arg[9]); + displace = atof(arg[10]); + + if (ntype <= 0 || ntype > atom->ntypes) + error->all("Invalid atom type in fix GCMC command"); + if (nexchanges < 0) error->all("Illegal fix GCMC command"); + if (nmcmoves < 0) error->all("Illegal fix GCMC command"); + if (seed <= 0) error->all("Illegal fix GCMC command"); + if (reservoir_temperature < 0.0) error->all("Illegal fix GCMC command"); + if (displace < 0.0) error->all("Illegal fix GCMC command"); + + // compute beta, lambda, sigma, and the zz factor + + beta = 1.0/(force->boltz*reservoir_temperature); + double PI = 4.0*atan(1.0); + double gas_mass = atom->mass[ntype]; + double lambda = sqrt(force->hplanck*force->hplanck/ + (2.0*PI*gas_mass*force->mvv2e* + force->boltz*reservoir_temperature)); + sigma = sqrt(force->boltz*reservoir_temperature/gas_mass/force->mvv2e); + zz = exp(beta*chemical_potential)/(pow(lambda,3)); + + // set defaults + + molflag = 0; + + // read options from end of input line + + options(narg-11,&arg[11]); + + // random number generator, same for all procs + + random_equal = new RanPark(lmp,seed); + + // random number generator, not the same for all procs + + random_unequal = new RanPark(lmp,seed); + + // compute the number of MC cycles that occur nevery timesteps + + ncycles = nexchanges + nmcmoves; + + // set up reneighboring + + force_reneighbor = 1; + next_reneighbor = update->ntimestep + 1; + + // zero out counters + + nmove_attempts = 0.0; + nmove_successes = 0.0; + ndel_attempts = 0.0; + ndel_successes = 0.0; + ninsert_attempts = 0.0; + ninsert_successes = 0.0; + + nmax = 0; + local_gas_list = NULL; +} + +/* ---------------------------------------------------------------------- */ + +FixGCMC::~FixGCMC() +{ + delete random_equal; + delete random_unequal; + memory->sfree(local_gas_list); +} + +/* ---------------------------------------------------------------------- */ + +int FixGCMC::setmask() +{ + int mask = 0; + mask |= PRE_EXCHANGE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixGCMC::init() +{ + // check that no deletable atoms are in atom->firstgroup + // deleting such an atom would not leave firstgroup atoms first + + int *type = atom->type; + + if (atom->firstgroup >= 0) { + int *mask = atom->mask; + int nlocal = atom->nlocal; + int firstgroupbit = group->bitmask[atom->firstgroup]; + + int flag = 0; + for (int i = 0; i < nlocal; i++) + if ((type[i] == ntype) && (mask[i] && firstgroupbit)) flag = 1; + + int flagall; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); + + if (flagall) + error->all("Cannot do GCMC on atoms in atom_modify first group"); + } + + // if molflag not set, warn if any deletable atom has a mol ID + + if (molflag == 0 && atom->molecule_flag) { + int *molecule = atom->molecule; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int flag = 0; + for (int i = 0; i < nlocal; i++) + if (type[i] == ntype) + if (molecule[i]) flag = 1; + int flagall; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); + if (flagall && comm->me == 0) + error->warning("Fix GCMC may delete atom with non-zero molecule ID"); + } + + if (molflag && atom->molecule_flag == 0) + error->all("Fix GCMC molecule command requires atom attribute molecule"); + + if (molflag != 0) error->all("Fix GCMC molecule feature does not yet work"); + + if (force->pair->single_enable == 0) + error->all("Fix GCMC incompatible with given pair_style"); +} + +/* ---------------------------------------------------------------------- + attempt particle insertions and deletions + done before exchange, borders, reneighbor + so that ghost atoms and neighbor lists will be correct +------------------------------------------------------------------------- */ + +void FixGCMC::pre_exchange() +{ + // just return if should not be called on this timestep + + if (next_reneighbor != update->ntimestep) return; + + if (domain->triclinic == 0) { + xlo = domain->boxlo[0]; + xhi = domain->boxhi[0]; + ylo = domain->boxlo[1]; + yhi = domain->boxhi[1]; + zlo = domain->boxlo[2]; + zhi = domain->boxhi[2]; + sublo = domain->sublo; + subhi = domain->subhi; + } else { + xlo = domain->boxlo_bound[0]; + xhi = domain->boxhi_bound[0]; + ylo = domain->boxlo_bound[1]; + yhi = domain->boxhi_bound[1]; + zlo = domain->boxlo_bound[2]; + zhi = domain->boxhi_bound[2]; + sublo = domain->sublo_lamda; + subhi = domain->subhi_lamda; + } + + volume = domain->xprd * domain->yprd * domain->zprd; + + // grow local_gas_list array if necessary + + if (atom->nlocal > nmax) { + memory->sfree(local_gas_list); + nmax = atom->nmax; + local_gas_list = (int *) memory->smalloc(nmax*sizeof(int), + "GCMC:local_gas_list"); + } + + int *type = atom->type; + ngas_local = 0; + for (int i = 0; i < atom->nlocal; i++) + if (type[i] == ntype) + local_gas_list[ngas_local++] = i; + + MPI_Allreduce(&ngas_local,&ngas,1,MPI_INT,MPI_SUM,world); + MPI_Scan(&ngas_local,&ngas_before,1,MPI_INT,MPI_SUM,world); + ngas_before -= ngas_local; + + // perform ncycles MC cycles + + for (int i = 0; i < ncycles; i++) { + int random_int_fraction = + static_cast(random_equal->uniform()*ncycles) + 1; + if (random_int_fraction <= nmcmoves) { + attempt_move(); + } else { + if (random_equal->uniform() < 0.5) attempt_deletion(); + else attempt_insertion(); + } + } + + next_reneighbor = update->ntimestep + nevery; +} + +/* ---------------------------------------------------------------------- + choose particle randomly across all procs and attempt displacement +------------------------------------------------------------------------- */ + +void FixGCMC::attempt_move() +{ + int i,iwhichglobal,iwhichlocal; + double rx,ry,rz; + double coord[3]; + double **x = atom->x; + + nmove_attempts += 1.0; + + int success = 0; + iwhichglobal = static_cast (ngas*random_equal->uniform()); + if ((iwhichglobal >= ngas_before) && + (iwhichglobal < ngas_before + ngas_local)) { + iwhichlocal = iwhichglobal - ngas_before; + i = local_gas_list[iwhichlocal]; + double energy_before = energy(i,x[i]); + double rsq = 1.1; + while (rsq > 1.0) { + rx = 2*random_unequal->uniform() - 1.0; + ry = 2*random_unequal->uniform() - 1.0; + if (domain->dimension == 3) rz = 2*random_unequal->uniform() - 1.0; + else rz = 0.0; + rsq = rx*rx + ry*ry + rz*rz; + } + coord[0] = x[i][0] + displace*rx; + coord[1] = x[i][1] + displace*ry; + coord[2] = x[i][2] + displace*rz; + double energy_after = energy(i,coord); + if (random_unequal->uniform() < exp(-beta*(energy_after - energy_before))) { + x[i][0] = coord[0]; + x[i][1] = coord[1]; + x[i][2] = coord[2]; + success = 1; + } + } + + int success_all = 0; + MPI_Allreduce(&success,&success_all,1,MPI_INT,MPI_MAX,world); + + if (success_all) { + nmove_successes += 1.0; + comm->borders(); + } + +} + +/* ---------------------------------------------------------------------- + attempt particle deletion +------------------------------------------------------------------------- */ + +void FixGCMC::attempt_deletion() +{ + ndel_attempts += 1.0; + + if (ngas == 0) return; + + int i,iwhichglobal,iwhichlocal; + AtomVec *avec = atom->avec; + + // choose particle randomly across all procs and delete it + // keep ngas, ngas_local, ngas_before, and local_gas_list current + // after each deletion + + int success = 0; + iwhichglobal = static_cast (ngas*random_equal->uniform()); + if ((iwhichglobal >= ngas_before) && + (iwhichglobal < ngas_before + ngas_local)) { + iwhichlocal = iwhichglobal - ngas_before; + i = local_gas_list[iwhichlocal]; + double deletion_energy = energy(i,atom->x[i]); + if (random_unequal->uniform() < + ngas*exp(beta*deletion_energy)/(zz*volume)) { + avec->copy(atom->nlocal-1,i,1); + atom->nlocal--; + local_gas_list[iwhichlocal] = local_gas_list[ngas_local-1]; + ngas_local--; + success = 1; + } + } + + int success_all = 0; + MPI_Allreduce(&success,&success_all,1,MPI_INT,MPI_MAX,world); + + if (success_all) { + ngas--; + ndel_successes += 1.0; + atom->natoms--; + if (iwhichglobal < ngas_before) ngas_before--; + comm->borders(); + if (atom->tag_enable) { + atom->tag_extend(); + if (atom->map_style) { + atom->map_init(); + atom->map_set(); + } + } + } +} + +/* ---------------------------------------------------------------------- + attempt particle insertion +------------------------------------------------------------------------- */ + +void FixGCMC::attempt_insertion() +{ + int flag,success; + double coord[3],lamda[3]; + double *newcoord; + + ninsert_attempts += 1.0; + + // choose random position for new atom within box + + coord[0] = xlo + random_equal->uniform() * (xhi-xlo); + coord[1] = ylo + random_equal->uniform() * (yhi-ylo); + coord[2] = zlo + random_equal->uniform() * (zhi-zlo); + + // check if new atom is in my sub-box or above it if I'm highest proc + // if so, add to my list via create_atom() + // initialize info about the atoms + // set group mask to "all" plus fix group + + if (domain->triclinic) { + domain->x2lamda(coord,lamda); + newcoord = lamda; + } else newcoord = coord; + + flag = 0; + if (newcoord[0] >= sublo[0] && newcoord[0] < subhi[0] && + newcoord[1] >= sublo[1] && newcoord[1] < subhi[1] && + newcoord[2] >= sublo[2] && newcoord[2] < subhi[2]) flag = 1; + + success = 0; + if (flag) { + int nall = atom->nlocal + atom->nghost; + double insertion_energy = energy(nall,coord); + if (random_unequal->uniform() < + zz*volume*exp(-beta*insertion_energy)/(ngas+1)) { + atom->avec->create_atom(ntype,coord); + int m = atom->nlocal - 1; + atom->type[m] = ntype; + atom->mask[m] = 1 | groupbit; + atom->v[m][0] = random_unequal->gaussian()*sigma; + atom->v[m][1] = random_unequal->gaussian()*sigma; + atom->v[m][2] = random_unequal->gaussian()*sigma; + + int nfix = modify->nfix; + Fix **fix = modify->fix; + for (int j = 0; j < nfix; j++) + if (fix[j]->create_attribute) fix[j]->set_arrays(m); + + if (atom->nlocal > nmax) { + nmax = atom->nmax; + local_gas_list = (int *) + memory->srealloc(local_gas_list,nmax*sizeof(int), + "GCMC:local_gas_list"); + } + + local_gas_list[ngas_local] = atom->nlocal; + ngas_local++; + success = 1; + } + } + + int success_all = 0; + MPI_Allreduce(&success,&success_all,1,MPI_INT,MPI_MAX,world); + + if (success_all) { + ngas++; + ninsert_successes += 1.0; + MPI_Scan(&ngas_local,&ngas_before,1,MPI_INT,MPI_SUM,world); + ngas_before -= ngas_local; + comm->borders(); + if (atom->tag_enable) { + atom->natoms++; + atom->tag_extend(); + if (atom->map_style) { + atom->map_init(); + atom->map_set(); + } + } + } +} + +/* ---------------------------------------------------------------------- + compute particle's interaction energy with the rest of the system +------------------------------------------------------------------------- */ + +double FixGCMC::energy(int i, double *coord) +{ + double delx,dely,delz,rsq; + + double **x = atom->x; + int *type = atom->type; + int nall = atom->nlocal + atom->nghost; + pair = force->pair; + cutsq = force->pair->cutsq; + + double fpair = 0.0; + double factor_coul = 1.0; + double factor_lj = 1.0; + + double total_energy = 0.0; + for (int j = 0; j < nall; j++) { + + if (i == j) continue; + + delx = coord[0] - x[j][0]; + dely = coord[1] - x[j][1]; + delz = coord[2] - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + int jtype = type[j]; + + if (rsq < cutsq[ntype][jtype]) + total_energy += + pair->single(i,j,ntype,jtype,rsq,factor_coul,factor_lj,fpair); + } + + return total_energy; +} + +/* ---------------------------------------------------------------------- + parse optional parameters at end of input line +------------------------------------------------------------------------- */ + +void FixGCMC::options(int narg, char **arg) +{ + if (narg < 0) error->all("Illegal fix GCMC command"); + + int iarg = 0; + while (iarg < narg) { + if (strcmp(arg[iarg],"molecule") == 0) { + if (iarg+2 > narg) error->all("Illegal fix GCMC command"); + if (strcmp(arg[iarg+1],"no") == 0) molflag = 0; + else if (strcmp(arg[iarg+1],"yes") == 0) molflag = 1; + else error->all("Illegal fix evaporate command"); + iarg += 2; + } else error->all("Illegal fix GCMC command"); + } +} + +/* ---------------------------------------------------------------------- + return acceptance ratios +------------------------------------------------------------------------- */ + +double FixGCMC::compute_vector(int n) +{ + if (n == 0) return nmove_attempts; + if (n == 1) return nmove_successes; + if (n == 2) return ndel_attempts; + if (n == 3) return ndel_successes; + if (n == 4) return ninsert_attempts; + if (n == 5) return ninsert_successes; + return 0.0; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double FixGCMC::memory_usage() +{ + double bytes = nmax * sizeof(int); + return bytes; +} + +/* ---------------------------------------------------------------------- + pack entire state of Fix into one write +------------------------------------------------------------------------- */ + +void FixGCMC::write_restart(FILE *fp) +{ + int n = 0; + double list[4]; + list[n++] = random_equal->state(); + list[n++] = random_unequal->state(); + list[n++] = next_reneighbor; + + if (comm->me == 0) { + int size = n * sizeof(double); + fwrite(&size,sizeof(int),1,fp); + fwrite(list,sizeof(double),n,fp); + } +} + +/* ---------------------------------------------------------------------- + use state info from restart file to restart the Fix +------------------------------------------------------------------------- */ + +void FixGCMC::restart(char *buf) +{ + int n = 0; + double *list = (double *) buf; + + seed = static_cast (list[n++]); + random_equal->reset(seed); + + seed = static_cast (list[n++]); + random_unequal->reset(seed); + + next_reneighbor = static_cast (list[n++]); +} diff --git a/src/MC/fix_gcmc.h b/src/MC/fix_gcmc.h new file mode 100644 index 0000000000..77b9f300e9 --- /dev/null +++ b/src/MC/fix_gcmc.h @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(gcmc,FixGCMC) + +#else + +#ifndef LMP_FIX_GCMC_H +#define LMP_FIX_GCMC_H + +#include "stdio.h" +#include "fix.h" + +namespace LAMMPS_NS { + +class FixGCMC : public Fix { + public: + FixGCMC(class LAMMPS *, int, char **); + ~FixGCMC(); + int setmask(); + void init(); + void pre_exchange(); + void attempt_move(); + void attempt_deletion(); + void attempt_insertion(); + double energy(int, double *); + double compute_vector(int); + double memory_usage(); + void write_restart(FILE *); + void restart(char *); + + private: + int ntype,nevery,seed; + int ncycles,nexchanges,nmcmoves; + int ngas; // # of gas molecules (or atoms) on all procs + int ngas_local; // # of gas molecules (or atoms) on this proc + int ngas_before; // # of gas molecules (or atoms) on procs < this proc + int molflag; // 0 = atomic, 1 = molecular system + double nmove_attempts; + double nmove_successes; + double ndel_attempts; + double ndel_successes; + double ninsert_attempts; + double ninsert_successes; + + int nmax; + double reservoir_temperature; + double chemical_potential; + double displace; + double beta,zz,sigma,volume; + double xlo,xhi,ylo,yhi,zlo,zhi; + double *sublo,*subhi; + int *local_gas_list; + double **cutsq; + class Pair *pair; + + class RanPark *random_equal; + class RanPark *random_unequal; + + void options(int, char **); +}; + +} + +#endif +#endif diff --git a/src/MC/pair_dsmc.cpp b/src/MC/pair_dsmc.cpp new file mode 100644 index 0000000000..b04dd8f6d7 --- /dev/null +++ b/src/MC/pair_dsmc.cpp @@ -0,0 +1,525 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_dsmc.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "error.h" +#include "domain.h" +#include "update.h" +#include "random_mars.h" +#include "limits.h" + +using namespace LAMMPS_NS; + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +/* ---------------------------------------------------------------------- */ + +PairDSMC::PairDSMC(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 0; + + total_number_of_collisions = 0; + max_particles = max_particle_list = 0; + next_particle = NULL; + random = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairDSMC::~PairDSMC() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(sigma); + memory->destroy(cut); + memory->destroy(V_sigma_max); + memory->destroy(particle_list); + memory->destroy(first); + memory->destroy(number); + } + + delete [] next_particle; + delete random; +} + +/* ---------------------------------------------------------------------- */ + +void PairDSMC::compute(int eflag, int vflag) +{ + double **x = atom->x; + double *mass = atom->mass; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (int i = 1; i <= atom->ntypes; ++i) + for (int j = 0; j < total_ncells; ++j) { + first[i][j] = -1; + number[i][j] = 0; + } + + if (atom->nmax > max_particles) { + delete [] next_particle; + max_particles = atom->nmax; + next_particle = new int[max_particles]; + } + + // find each particle's cell and sort by type + // assume a constant volume and shape simulation domain + // skip particle if outside processor domain + + for (int i = 0; i < nlocal; ++i) { + int xcell = static_cast((x[i][0] - domain->boxlo[0])/cellx); + int ycell = static_cast((x[i][1] - domain->boxlo[1])/celly); + int zcell = static_cast((x[i][2] - domain->boxlo[2])/cellz); + + if ((xcell < 0) or (xcell > ncellsx-1) or + (ycell < 0) or (ycell > ncellsy-1) or + (zcell < 0) or (zcell > ncellsz-1)) continue; + + int icell = xcell + ycell*ncellsx + zcell*ncellsx*ncellsy; + itype = type[i]; + next_particle[i] = first[itype][icell]; + first[itype][icell] = i; + number[itype][icell]++; + } + + for (int icell = 0; icell < total_ncells; ++icell) { + + for (itype = 1; itype <= atom->ntypes; ++itype) { + number_of_A = number[itype][icell]; + if (number_of_A > max_particle_list) { + max_particle_list = number_of_A; + memory->grow(particle_list,atom->ntypes+1,max_particle_list, + "pair:particle_list"); + } + + int m = first[itype][icell]; + for (int k = 0; k < number_of_A; k++) { + particle_list[itype][k] = m; + m = next_particle[m]; + } + } + + for (itype = 1; itype <= atom->ntypes; ++itype) { + imass = mass[itype]; + number_of_A = number[itype][icell]; + + for (jtype = itype; jtype <= atom->ntypes; ++jtype) { + jmass = mass[jtype]; + number_of_B = number[jtype][icell]; + + reduced_mass = imass*jmass/(imass + jmass); + total_mass = imass + jmass; + jmass_tmass = jmass/total_mass; + imass_tmass = imass/total_mass; + + // if necessary, recompute V_sigma_max values + + if (recompute_vsigmamax_stride && + (update->ntimestep % recompute_vsigmamax_stride == 0)) + recompute_V_sigma_max(icell); + + // # of collisions to perform for itype-jtype pairs + + double &Vs_max = V_sigma_max[itype][jtype]; + double num_of_collisions_double = number_of_A * number_of_B * + weighting * Vs_max * update->dt / vol; + + if ((itype == jtype) and number_of_B) + num_of_collisions_double *= + 0.5 * double(number_of_B - 1) / double(number_of_B); + + int num_of_collisions = + convert_double_to_equivalent_int(num_of_collisions_double); + + if (num_of_collisions > number_of_A) + error->warning("Pair dsmc: num_of_collisions > number_of_A",0); + if (num_of_collisions > number_of_B) + error->warning("Pair dsmc: num_of_collisions > number_of_B",0); + + // perform collisions on pairs of particles in icell + + for (int k = 0; k < num_of_collisions; k++) { + if ((number_of_A < 1) or (number_of_B < 1)) break; + int ith_A = static_cast(random->uniform()*number_of_A); + int jth_B = static_cast(random->uniform()*number_of_B); + int i = particle_list[itype][ith_A]; + int j = particle_list[jtype][jth_B]; + if (i == j) { + k--; + continue; + } + double probability = V_sigma(i,j)/Vs_max; + if (probability > random->uniform()) scatter_random(i,j,icell); + } + } + } + } +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairDSMC::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(V_sigma_max,n+1,n+1,"pair:V_sigma_max"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairDSMC::settings(int narg, char **arg) +{ + if (narg != 6) error->all("Illegal pair_style command"); + + cut_global = 0.0; + max_cell_size = force->numeric(arg[0]); + seed = force->inumeric(arg[1]); + weighting = force->numeric(arg[2]); + T_ref = force->numeric(arg[3]); + recompute_vsigmamax_stride = force->inumeric(arg[4]); + vsigmamax_samples = force->inumeric(arg[5]); + + // initialize Marsaglia RNG with processor-unique seed + + if (max_cell_size <= 0.0) error->all("Illegal pair_style command"); + if (seed <= 0) error->all("Illegal pair_style command"); + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); + + kT_ref = force->boltz*T_ref; + + // 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 PairDSMC::coeff(int narg, char **arg) +{ + if (narg < 3 || narg > 4) 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 sigma_one = force->numeric(arg[2]); + + double cut_one = cut_global; + if (narg == 4) cut_one = force->numeric(arg[3]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + sigma[i][j] = sigma_one; + 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 PairDSMC::init_style() +{ + ncellsx = ncellsy = ncellsz = 1; + while (((domain->boxhi[0] - domain->boxlo[0])/ncellsx) > max_cell_size) + ncellsx++; + while (((domain->boxhi[1] - domain->boxlo[1])/ncellsy) > max_cell_size) + ncellsy++; + while (((domain->boxhi[2] - domain->boxlo[2])/ncellsz) > max_cell_size) + ncellsz++; + + cellx = (domain->boxhi[0] - domain->boxlo[0])/ncellsx; + celly = (domain->boxhi[1] - domain->boxlo[1])/ncellsy; + cellz = (domain->boxhi[2] - domain->boxlo[2])/ncellsz; + + if (comm->me == 0) { + if (screen) fprintf(screen,"DSMC cell size = %g x %g x %g\n", + cellx,celly,cellz); + if (logfile) fprintf(logfile,"DSMC cell size = %g x %g x %g\n", + cellx,celly,cellz); + } + + total_ncells = ncellsx*ncellsy*ncellsz; + vol = cellx*celly*cellz; + + memory->create(particle_list,atom->ntypes+1,0,"pair:particle_list"); + memory->create(first,atom->ntypes+1,total_ncells,"pair:first"); + memory->create(number,atom->ntypes+1,total_ncells,"pair:number"); + + for (int i = 1; i <= atom->ntypes; i++) + for (int j = 1; j <= atom->ntypes; j++) + V_sigma_max[i][j] = 0.0; + + two_pi = 8.0*atan(1.0); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairDSMC::init_one(int i, int j) +{ + if (setflag[i][j] == 0) cut[i][j] = 0.0; + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairDSMC::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(&sigma[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairDSMC::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(&sigma[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairDSMC::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&max_cell_size,sizeof(double),1,fp); + fwrite(&seed,sizeof(int),1,fp); + fwrite(&offset_flag,sizeof(int),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairDSMC::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + fread(&max_cell_size,sizeof(double),1,fp); + fread(&seed,sizeof(int),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(&max_cell_size,1,MPI_DOUBLE,0,world); + MPI_Bcast(&seed,1,MPI_INT,0,world); + MPI_Bcast(&offset_flag,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); + + // initialize Marsaglia RNG with processor-unique seed + // same seed that pair_style command initially specified + + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); +} + +/*------------------------------------------------------------------------- + rezero and recompute the V_sigma_max values this timestep for use during + the next nrezero timesteps +-------------------------------------------------------------------------*/ + +void PairDSMC::recompute_V_sigma_max(int icell) +{ + int i,j,k; + double Vsigma_max = 0; + + if (number_of_A && number_of_B) { + for (k = 0; k < vsigmamax_samples; k++) { + i = particle_list[itype] + [static_cast(random->uniform()*number_of_A)]; + j = particle_list[jtype] + [static_cast(random->uniform()*number_of_B)]; + if (i == j) continue; + Vsigma_max = MAX(Vsigma_max,V_sigma(i,j)); + } + } + V_sigma_max[itype][jtype] = Vsigma_max; +} + +/*------------------------------------------------------------------------- + VHS model + compute the velocity vector difference between i and j and multiply by + their combined collision cross section, sigma, for neutral-neutral + collisions using the Variable Hard Sphere model +-------------------------------------------------------------------------*/ + +double PairDSMC::V_sigma(int i, int j) +{ + double relative_velocity_sq,relative_velocity,pair_sigma; + double delv[3]; + double *vi = atom->v[i]; + double *vj = atom->v[j]; + + subtract3d(vi,vj,delv); + relative_velocity_sq = dot3d(delv,delv); + relative_velocity = sqrt(relative_velocity_sq); + + // from Bird eq 4.63, and omega=0.67 + // (omega - 0.5) = 0.17 + // 1/GAMMA(2.5 - omega) = 1.06418029298371 + + if (relative_velocity_sq != 0.0) + pair_sigma = sigma[itype][jtype]* + pow(kT_ref/(0.5*reduced_mass*relative_velocity_sq),0.17) * + 1.06418029298371; + else + pair_sigma = 0.0; + + return relative_velocity*pair_sigma; +} + +/*------------------------------------------------------------------------- + generate new velocities for collided particles +-------------------------------------------------------------------------*/ + +void PairDSMC::scatter_random(int i, int j, int icell) +{ + double mag_delv,cos_phi,cos_squared,r,theta; + double delv[3],vcm[3]; + double *vi = atom->v[i]; + double *vj = atom->v[j]; + + subtract3d(vi,vj,delv); + if (itype == jtype) mag_delv = sqrt(dot3d(delv,delv))*0.5; + else mag_delv = sqrt(dot3d(delv,delv)); + + cos_phi = 1.0 - (2.0*random->uniform()); + cos_squared = MIN(1.0,cos_phi*cos_phi); + r = sqrt(1.0 - cos_squared); + delv[0] = cos_phi*mag_delv; + theta = two_pi*random->uniform(); + delv[1] = r*mag_delv*cos(theta); + delv[2] = r*mag_delv*sin(theta); + + if (itype == jtype) { + vcm[0] = (vi[0]+vj[0])*0.5; + vcm[1] = (vi[1]+vj[1])*0.5; + vcm[2] = (vi[2]+vj[2])*0.5; + vi[0] = vcm[0] + delv[0]; + vi[1] = vcm[1] + delv[1]; + vi[2] = vcm[2] + delv[2]; + vj[0] = vcm[0] - delv[0]; + vj[1] = vcm[1] - delv[1]; + vj[2] = vcm[2] - delv[2]; + } else { + vcm[0] = vi[0]*imass_tmass + vj[0]*jmass_tmass; + vcm[1] = vi[1]*imass_tmass + vj[1]*jmass_tmass; + vcm[2] = vi[2]*imass_tmass + vj[2]*jmass_tmass; + vi[0] = vcm[0] + delv[0]*jmass_tmass; + vi[1] = vcm[1] + delv[1]*jmass_tmass; + vi[2] = vcm[2] + delv[2]*jmass_tmass; + vj[0] = vcm[0] - delv[0]*imass_tmass; + vj[1] = vcm[1] - delv[1]*imass_tmass; + vj[2] = vcm[2] - delv[2]*imass_tmass; + } + + total_number_of_collisions++; +} + +/* ---------------------------------------------------------------------- + This method converts the double supplied by the calling function into + an int, which is returned. By adding a random number between 0 and 1 + to the double before converting it to an int, we ensure that, + statistically, we round down with probability identical to the + remainder and up the rest of the time. So even though we're using an + integer, we're statistically matching the exact expression represented + by the double. +------------------------------------------------------------------------- */ + +int PairDSMC::convert_double_to_equivalent_int(double input_double) +{ + if (input_double > INT_MAX) + error->all("Tried to convert a double to int, but input_double > INT_MAX"); + + int output_int = static_cast(input_double + random->uniform()); + return output_int; +} diff --git a/src/MC/pair_dsmc.h b/src/MC/pair_dsmc.h new file mode 100644 index 0000000000..7e2b784f73 --- /dev/null +++ b/src/MC/pair_dsmc.h @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dsmc,PairDSMC) + +#else + +#ifndef LMP_PAIR_DSMC_H +#define LMP_PAIR_DSMC_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairDSMC : public Pair { + public: + PairDSMC(class LAMMPS *); + virtual ~PairDSMC(); + virtual void compute(int, int); + virtual void settings(int, char **); + void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + + private: + double cut_global; + double **cut; + double **sigma; + + double cellx; + double celly; + double cellz; + int ncellsx; + int ncellsy; + int ncellsz; + int total_ncells; + int total_number_of_collisions; + int recompute_vsigmamax_stride; + int vsigmamax_samples; + double T_ref; + double kT_ref; + double two_pi; + double max_cell_size; + + int seed; + int number_of_A; + int number_of_B; + int max_particle_list; + + class RanMars *random; + + int **particle_list; + int **first; + int **number; + + double **V_sigma_max; + + int max_particles; + int *next_particle; + + int itype; + int jtype; + + double imass; + double jmass; + double total_mass; + double reduced_mass; + double imass_tmass; + double jmass_tmass; + double vol; + double weighting; + + void allocate(); + void recompute_V_sigma_max(int); + double V_sigma(int, int); + void scatter_random(int, int, int); + int convert_double_to_equivalent_int(double); + + inline void subtract3d(const double *v1, const double *v2, double *v3) { + v3[0] = v2[0] - v1[0]; + v3[1] = v2[1] - v1[1]; + v3[2] = v2[2] - v1[2]; + } + + inline double dot3d(const double *v1, const double *v2) { + return( v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] ); + } +}; + +} + +#endif +#endif From 58b907b506f0982f19282b636c11685e44a5f01e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:31:38 +0000 Subject: [PATCH 030/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6797 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MC/Install.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/MC/Install.sh b/src/MC/Install.sh index 60e34982ca..845b5b1c2e 100644 --- a/src/MC/Install.sh +++ b/src/MC/Install.sh @@ -2,14 +2,30 @@ if (test $1 = 1) then + cp fix_bond_break.cpp .. + cp fix_bond_create.cpp .. + cp fix_bond_swap.cpp .. + cp fix_gcmc.cpp .. cp pair_dsmc.cpp .. + cp fix_bond_break.h .. + cp fix_bond_create.h .. + cp fix_bond_swap.h .. + cp fix_gcmc.h .. cp pair_dsmc.h .. elif (test $1 = 0) then + rm -f ../fix_bond_break.cpp + rm -f ../fix_bond_create.cpp + rm -f ../fix_bond_swap.cpp + rm -f ../fix_gcmc.cpp rm -f ../pair_dsmc.cpp + rm -f ../fix_bond_break.h + rm -f ../fix_bond_create.h + rm -f ../fix_bond_swap.h + rm -f ../fix_gcmc.h rm -f ../pair_dsmc.h fi From e4b59d189f599dc496cd596b6dd45b04182a139a Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:34:45 +0000 Subject: [PATCH 031/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6798 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_bond_break.html | 4 ++++ doc/fix_bond_break.txt | 4 ++++ doc/fix_bond_create.html | 4 ++++ doc/fix_bond_create.txt | 4 ++++ doc/fix_bond_swap.html | 4 ++++ doc/fix_bond_swap.txt | 4 ++++ doc/pair_dsmc.html | 2 +- doc/pair_dsmc.txt | 2 +- 8 files changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/fix_bond_break.html b/doc/fix_bond_break.html index 182874d073..57a5757bd5 100644 --- a/doc/fix_bond_break.html +++ b/doc/fix_bond_break.html @@ -128,6 +128,10 @@ minimization.

    Restrictions:

    +

    This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    Currently, there are 2 restrictions for using this fix. We may relax these in the future if there are new models that would be enabled by it. diff --git a/doc/fix_bond_break.txt b/doc/fix_bond_break.txt index f63c3c3718..151c4155df 100755 --- a/doc/fix_bond_break.txt +++ b/doc/fix_bond_break.txt @@ -117,6 +117,10 @@ minimization"_minimize.html. [Restrictions:] +This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + Currently, there are 2 restrictions for using this fix. We may relax these in the future if there are new models that would be enabled by it. diff --git a/doc/fix_bond_create.html b/doc/fix_bond_create.html index 1c7eb027d3..6798e0696d 100644 --- a/doc/fix_bond_create.html +++ b/doc/fix_bond_create.html @@ -185,6 +185,10 @@ minimization.

    Restrictions:

    +

    This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    Currently, there are 2 restrictions for using this fix. We may relax these in the future if there are new models that would be enabled by it. diff --git a/doc/fix_bond_create.txt b/doc/fix_bond_create.txt index 580f888dfc..4a822a3672 100755 --- a/doc/fix_bond_create.txt +++ b/doc/fix_bond_create.txt @@ -173,6 +173,10 @@ minimization"_minimize.html. [Restrictions:] +This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + Currently, there are 2 restrictions for using this fix. We may relax these in the future if there are new models that would be enabled by it. diff --git a/doc/fix_bond_swap.html b/doc/fix_bond_swap.html index a4ced35353..6952669569 100644 --- a/doc/fix_bond_swap.html +++ b/doc/fix_bond_swap.html @@ -160,6 +160,10 @@ minimization.

    Restrictions:

    +

    This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    The setings of the "special_bond" command must be 0,1,1 in order to use this fix, which is typical of bead-spring chains with FENE or harmonic bonds. This means that pairwise interactions between bonded diff --git a/doc/fix_bond_swap.txt b/doc/fix_bond_swap.txt index eba291c8c7..753f6f8f81 100755 --- a/doc/fix_bond_swap.txt +++ b/doc/fix_bond_swap.txt @@ -157,6 +157,10 @@ minimization"_minimize.html. [Restrictions:] +This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + The setings of the "special_bond" command must be 0,1,1 in order to use this fix, which is typical of bead-spring chains with FENE or harmonic bonds. This means that pairwise interactions between bonded diff --git a/doc/pair_dsmc.html b/doc/pair_dsmc.html index 573d85f49b..8b1676fe0b 100644 --- a/doc/pair_dsmc.html +++ b/doc/pair_dsmc.html @@ -122,7 +122,7 @@ continued past the restart time.

    Restrictions:

    -

    This style is part of the "dsmc" package. It is only enabled if +

    This style is part of the "mc" package. It is only enabled if LAMMPS was built with that package. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_dsmc.txt b/doc/pair_dsmc.txt index 00988a0264..0edfbffa62 100644 --- a/doc/pair_dsmc.txt +++ b/doc/pair_dsmc.txt @@ -119,7 +119,7 @@ This pair style can only be used via the {pair} keyword of the [Restrictions:] -This style is part of the "dsmc" package. It is only enabled if +This style is part of the "mc" package. It is only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#2_3 section for more info. From 19399847e3e045603623f85222bc307a212c1b27 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:34:50 +0000 Subject: [PATCH 032/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6799 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_gcmc.html | 187 ++++++++++++++++++++++++++++++++++++++++++++++ doc/fix_gcmc.txt | 169 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 doc/fix_gcmc.html create mode 100644 doc/fix_gcmc.txt diff --git a/doc/fix_gcmc.html b/doc/fix_gcmc.html new file mode 100644 index 0000000000..3bd068858c --- /dev/null +++ b/doc/fix_gcmc.html @@ -0,0 +1,187 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    fix gcmc command +

    +

    Syntax: +

    +
    fix ID group-ID gcmc N X M type seed T mu displace keyword values ... 
    +
    +
    • ID, group-ID are documented in fix command + +
    • gcmc = style name of this fix command + +
    • N = invoke this fix every N steps + +
    • X = number of exchanges to attempt every N steps + +
    • M = number of MC displacements to attempt every N steps + +
    • type = atom type of exchanged particles + +
    • seed = random # seed (positive integer) + +
    • T = temperature of the ideal gas reservoir (temperature units) + +
    • mu = chemical potential of the ideal gas reservoir (energy units) + +
    • displace = maximum Monte Carlo displacement distance (length units) + +
    • zero or more keyword/value pairs may be appended to args + +
      keyword = molecule
      +  molecule value = no or yes 
      +
      + +
    +

    Examples: +

    +
    fix 2 all gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01
    +fix 3 all gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes 
    +
    +

    Description: +

    +

    This fix performs grand canonical Monte Carlo (GCMC) exchanges of +particles of the given type with an imaginary ideal gas reservoir at +the specified T and chemical potential (mu) as discussed in +(Frenkel). If used with the fix nvt command, +simulations in the grand canonical enemble (muVT, constant chemical +potential, constant volume, and constant temperature) can be +performed. Specific uses include computing isotherms in microporous +materials, or computing vapor-liquid coexistence curves. +

    +

    Perform up to X exchanges of particles of the given type between the +simulation domain and the imaginary reservoir every N timesteps. Also +perform M Monte Carlo displacements of particles of the given type +within the simulation domain. M should typically be chosen to be +approximately equal to the expected number of particles of the given +type within the domain, which will result in roughly one MC +translation per particle per MC cycle. +

    +

    This fix cannot be used to perform MC displacements of particles other +than the exchanged type. All particles in the simulation domain can be +moved using regular time integration displacements, e.g. via +fix_nvt, resulting in a hybrid GCMC+MD simulation. +

    +

    If used with fix_nvt, the temperature of the imaginary +reservoir, T, should be set to be equivalent to the target temperature +used in fix_nvt. Otherwise, the imaginary reservoir +will not be in thermal equilibrium with the simulation domain. +

    +

    Note that neighbor lists are re-built every timestep that this fix is +invoked, so you should not set N to be too small. However, periodic +rebuilds are necessary in order to avoid dangerous rebuilds and missed +interactions. Specifically, avoid performing so many MC displacements +per timestep that a particle can move beyond the neighbor list skin +distance. See the neighbor command for details. +

    +

    When a particle is to be inserted, its coordinates are chosen as a +random position within the current simulation domain, and its velocity +is randomly chosen from the specified temperature distribution given +by T. +

    +

    Exchanged particles have the specified atom type and are assigned to +two groups: the default group "all" and the group specified in the fix +gcmc command (which can also be "all"). +

    +

    If the setting for the molecule keyword is no, then only single +atoms are exchanged. In this case, you should ensure you do not +delete only a portion of a molecule (only some of its atoms), or +LAMMPS will soon generate an error when it tries to find those atoms. +LAMMPS will warn you if any of the atoms eligible for deletion have a +non-zero molecule ID, but does not check for this at the time of +deletion. +

    +

    If the setting for the molecule keyword is yes, entire molecules +are exchanged. This feature is not yet supported. +

    +

    Use of this fix typically will cause the number of atoms to fluctuate, +therefore, you will want to use the +compute_modify command to insure that the +current number of atoms is used as a normalizing factor each time +temperature is computed. Here is the necessary command: +

    +
    compute_modify thermo_temp dynamic yes 
    +
    +

    If LJ units are used, note that a value of 0.18292026 is used by this +fix as the reduced value for Planck's constant. This value was +derived from LJ paramters for argon, where h* = h/sqrt(sigma^2 * +epsilon * mass), sigma = 3.429 angstroms, epsilon/k = 121.85 K, and +mass = 39.948 amu. +

    +

    Restart, fix_modify, output, run start/stop, minimize info: +

    +

    This fix writes the state of the deposition to binary restart +files. This includes information about the random +number generator seed, the next timestep for MC exchanges, etc. See +the read_restart command for info on how to +re-specify a fix in an input script that reads a restart file, so that +the operation of the fix continues in an uninterrupted fashion. +

    +

    None of the fix_modify options are relevant to this +fix. +

    +

    This fix computes a global vector of length 6, which can be accessed +by various output commands. The vector +values are the following global cummulative quantities: +

    +
    • 1 = displacement attempts +
    • 2 = displacement successes +
    • 3 = deletion attempts +
    • 4 = deletion successes +
    • 5 = insertion attempts +
    • 6 = insertion successes +
    +

    The vector values calculated by this fix are "extensive". +

    +

    No parameter of this fix can be used with the start/stop keywords of +the run command. This fix is not invoked during energy +minimization. +

    +

    Restrictions: +

    +

    This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    +

    Do not set "neigh_modify once yes" or else this fix will never be +called. Reneighboring is required. +

    +

    You cannot currently exchange charged particles or molecules with a +net charge. +

    +

    Only pairwise interactions, as defined by the +pair_style command, are included in this +calculation. Long-range interactions due to a +kspace_style command are not included. Not all +pair potentials can be evaluated in a pairwise mode as required by +this fix. For example, 3-body potentials, such as +Tersoff and Stillinger-Weber cannot +be used. EAM potentials for metals only include the +pair potential portion of the EAM interaction, not the embedding term. +

    +

    Related commands: +

    +

    fix_nvt, neighbor, +fix_deposit, fix_evaporate +

    +

    Default: +

    +

    The option defaults are molecule = no. +

    +
    + + + +

    (Frenkel) Frenkel and Smit, Understanding Molecular Simulation, +Academic Press, London, 2002. +

    + diff --git a/doc/fix_gcmc.txt b/doc/fix_gcmc.txt new file mode 100644 index 0000000000..d2c810f4bf --- /dev/null +++ b/doc/fix_gcmc.txt @@ -0,0 +1,169 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix gcmc command :h3 + +[Syntax:] + +fix ID group-ID gcmc N X M type seed T mu displace keyword values ... :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +gcmc = style name of this fix command :l +N = invoke this fix every N steps :l +X = number of exchanges to attempt every N steps :l +M = number of MC displacements to attempt every N steps :l +type = atom type of exchanged particles :l +seed = random # seed (positive integer) :l +T = temperature of the ideal gas reservoir (temperature units) :l +mu = chemical potential of the ideal gas reservoir (energy units) :l +displace = maximum Monte Carlo displacement distance (length units) :l +zero or more keyword/value pairs may be appended to args :l +keyword = {molecule} + {molecule} value = {no} or {yes} :pre +:ule + +[Examples:] + +fix 2 all gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01 +fix 3 all gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes :pre + +[Description:] + +This fix performs grand canonical Monte Carlo (GCMC) exchanges of +particles of the given type with an imaginary ideal gas reservoir at +the specified T and chemical potential (mu) as discussed in +"(Frenkel)"_#Frenkel. If used with the "fix nvt"_fix_nh.html command, +simulations in the grand canonical enemble (muVT, constant chemical +potential, constant volume, and constant temperature) can be +performed. Specific uses include computing isotherms in microporous +materials, or computing vapor-liquid coexistence curves. + +Perform up to X exchanges of particles of the given type between the +simulation domain and the imaginary reservoir every N timesteps. Also +perform M Monte Carlo displacements of particles of the given type +within the simulation domain. M should typically be chosen to be +approximately equal to the expected number of particles of the given +type within the domain, which will result in roughly one MC +translation per particle per MC cycle. + +This fix cannot be used to perform MC displacements of particles other +than the exchanged type. All particles in the simulation domain can be +moved using regular time integration displacements, e.g. via +"fix_nvt"_fix_nvt.html, resulting in a hybrid GCMC+MD simulation. + +If used with "fix_nvt"_fix_nvt.html, the temperature of the imaginary +reservoir, T, should be set to be equivalent to the target temperature +used in "fix_nvt"_fix_nvt.html. Otherwise, the imaginary reservoir +will not be in thermal equilibrium with the simulation domain. + +Note that neighbor lists are re-built every timestep that this fix is +invoked, so you should not set N to be too small. However, periodic +rebuilds are necessary in order to avoid dangerous rebuilds and missed +interactions. Specifically, avoid performing so many MC displacements +per timestep that a particle can move beyond the neighbor list skin +distance. See the "neighbor"_neighbor.html command for details. + +When a particle is to be inserted, its coordinates are chosen as a +random position within the current simulation domain, and its velocity +is randomly chosen from the specified temperature distribution given +by T. + +Exchanged particles have the specified atom type and are assigned to +two groups: the default group "all" and the group specified in the fix +gcmc command (which can also be "all"). + +If the setting for the {molecule} keyword is {no}, then only single +atoms are exchanged. In this case, you should ensure you do not +delete only a portion of a molecule (only some of its atoms), or +LAMMPS will soon generate an error when it tries to find those atoms. +LAMMPS will warn you if any of the atoms eligible for deletion have a +non-zero molecule ID, but does not check for this at the time of +deletion. + +If the setting for the {molecule} keyword is {yes}, entire molecules +are exchanged. This feature is not yet supported. + +Use of this fix typically will cause the number of atoms to fluctuate, +therefore, you will want to use the +"compute_modify"_compute_modify.html command to insure that the +current number of atoms is used as a normalizing factor each time +temperature is computed. Here is the necessary command: + +compute_modify thermo_temp dynamic yes :pre + +If LJ units are used, note that a value of 0.18292026 is used by this +fix as the reduced value for Planck's constant. This value was +derived from LJ paramters for argon, where h* = h/sqrt(sigma^2 * +epsilon * mass), sigma = 3.429 angstroms, epsilon/k = 121.85 K, and +mass = 39.948 amu. + +[Restart, fix_modify, output, run start/stop, minimize info:] + +This fix writes the state of the deposition to "binary restart +files"_restart.html. This includes information about the random +number generator seed, the next timestep for MC exchanges, etc. See +the "read_restart"_read_restart.html command for info on how to +re-specify a fix in an input script that reads a restart file, so that +the operation of the fix continues in an uninterrupted fashion. + +None of the "fix_modify"_fix_modify.html options are relevant to this +fix. + +This fix computes a global vector of length 6, which can be accessed +by various "output commands"_Section_howto.html#4_15. The vector +values are the following global cummulative quantities: + +1 = displacement attempts +2 = displacement successes +3 = deletion attempts +4 = deletion successes +5 = insertion attempts +6 = insertion successes :ul + +The vector values calculated by this fix are "extensive". + +No parameter of this fix can be used with the {start/stop} keywords of +the "run"_run.html command. This fix is not invoked during "energy +minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the "mc" package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Do not set "neigh_modify once yes" or else this fix will never be +called. Reneighboring is required. + +You cannot currently exchange charged particles or molecules with a +net charge. + +Only pairwise interactions, as defined by the +"pair_style"_pair_style.html command, are included in this +calculation. Long-range interactions due to a +"kspace_style"_kspace_style.html command are not included. Not all +pair potentials can be evaluated in a pairwise mode as required by +this fix. For example, 3-body potentials, such as +"Tersoff"_pair_tersoff.html and "Stillinger-Weber"_pair_sw.html cannot +be used. "EAM"_pair_eam.html potentials for metals only include the +pair potential portion of the EAM interaction, not the embedding term. + +[Related commands:] + +"fix_nvt"_fix_nvt.html, "neighbor"_neighbor.html, +"fix_deposit"_fix_deposit.html, "fix_evaporate"_fix_evaporate.html + +[Default:] + +The option defaults are molecule = no. + +:line + +:link(Frenkel) +[(Frenkel)] Frenkel and Smit, Understanding Molecular Simulation, +Academic Press, London, 2002. From 8f75fcbb8b8253fc15a88741497ed36e32421709 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:36:43 +0000 Subject: [PATCH 033/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6800 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 18 +++++++++--------- doc/Section_commands.txt | 1 + doc/fix.html | 1 + doc/fix.txt | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 17be7419e2..3f364a22b9 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -338,15 +338,15 @@ of each style or click on the style itself for a full description:
    - - - - - - - - - + + + + + + + +
    adaptaddforceaveforceave/atomave/correlateave/histoave/spatialave/time
    bond/breakbond/createbond/swapbox/relaxdeformdepositdragdt/reset
    efieldenforce2devaporateexternalfreezegravityheatindent
    langevinlineforcemomentummovemsstnebnphnph/asphere
    nph/spherenptnpt/aspherenpt/spherenvenve/aspherenve/limitnve/noforce
    nve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fccplaneforcepoems
    pourpress/berendsenprintqeq/combreax/bondsrecenterrestrainrigid
    rigid/nverigid/nvtsetforceshakespringspring/rgspring/selfsrd
    store/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmdttmviscosity
    viscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93wall/reflectwall/region
    wall/srd +
    efieldenforce2devaporateexternalfreezegcmcgravityheat
    indentlangevinlineforcemomentummovemsstnebnph
    nph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/aspherenve/limit
    nve/noforcenve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fccplaneforce
    poemspourpress/berendsenprintqeq/combreax/bondsrecenterrestrain
    rigidrigid/nverigid/nvtsetforceshakespringspring/rgspring/self
    srdstore/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmdttm
    viscosityviscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93wall/reflect
    wall/regionwall/srd

    These are fix styles contributed by users, which can be used if diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 2637513cc1..05885633e3 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -418,6 +418,7 @@ of each style or click on the style itself for a full description: "evaporate"_fix_evaporate.html, "external"_fix_external.html, "freeze"_fix_freeze.html, +"gcmc"_fix_gcmc.html, "gravity"_fix_gravity.html, "heat"_fix_heat.html, "indent"_fix_indent.html, diff --git a/doc/fix.html b/doc/fix.html index bd47e95a4d..7819565f99 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -181,6 +181,7 @@ list of fix styles available in LAMMPS:

  • external - callback to an external driver program
  • freeze - freeze atoms in a granular simulation
  • gravity - add gravity to atoms in a granular simulation +
  • gcmc - grand canonical insertions/deletions
  • heat - add/subtract momentum-conserving heat
  • indent - impose force due to an indenter
  • langevin - Langevin temperature control diff --git a/doc/fix.txt b/doc/fix.txt index 749bef0353..7ffba56316 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -176,6 +176,7 @@ list of fix styles available in LAMMPS: "external"_fix_external.html - callback to an external driver program "freeze"_fix_freeze.html - freeze atoms in a granular simulation "gravity"_fix_gravity.html - add gravity to atoms in a granular simulation +"gcmc"_fix_gcmc.html - grand canonical insertions/deletions "heat"_fix_heat.html - add/subtract momentum-conserving heat "indent"_fix_indent.html - impose force due to an indenter "langevin"_fix_langevin.html - Langevin temperature control From 499db7f9cd8582016c15398c221f8cbc59d4fab5 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:39:32 +0000 Subject: [PATCH 034/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6801 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_intro.html | 1 + doc/Section_intro.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/Section_intro.html b/doc/Section_intro.html index db64d2821a..065b5b5547 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -246,6 +246,7 @@ molecular dynamics options:
  • real-time visualization and interactive MD
  • atom-to-continuum coupling with finite elements
  • coupled rigid body integration via the POEMS library +
  • grand canonical Monte Carlo insertions/deletions
  • Direct Simulation Monte Carlo for low-density fluids
  • Peridynamics mesoscale modeling
  • targeted and steered molecular dynamics diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 28c9a1a9d9..3c570b18ab 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -242,6 +242,7 @@ molecular dynamics options: "real-time visualization and interactive MD"_fix_imd.html "atom-to-continuum coupling"_fix_atc.html with finite elements coupled rigid body integration via the "POEMS"_fix_poems.html library +"grand canonical Monte Carlo"_doc/fix_gcmc.html insertions/deletions "Direct Simulation Monte Carlo"_pair_dsmc.html for low-density fluids "Peridynamics mesoscale modeling"_pair_peri.html "targeted"_fix_tmd.html and "steered"_fix_smd.html molecular dynamics From b5a3443db744e11ea300cf879f1f80ad3cb32697 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 15:40:54 +0000 Subject: [PATCH 035/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6803 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 50af95af92..e8ed626307 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "24 Aug 2011" +#define LAMMPS_VERSION "25 Aug 2011" From d0d785e3a2c9922a0d9017c713d136c6a656136f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 16:17:31 +0000 Subject: [PATCH 036/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6807 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Manual.html | 156 +++++++++++++++++++++--------- doc/Manual.txt | 187 +++++++++++++++++++++--------------- doc/Section_accelerate.html | 26 ++--- doc/Section_accelerate.txt | 26 ++--- doc/Section_commands.html | 2 +- doc/Section_commands.txt | 2 +- doc/Section_errors.html | 16 +-- doc/Section_errors.txt | 16 +-- doc/Section_example.html | 2 +- doc/Section_example.txt | 2 +- doc/Section_history.html | 10 +- doc/Section_history.txt | 10 +- doc/Section_howto.html | 104 ++++++++++---------- doc/Section_howto.txt | 104 ++++++++++---------- doc/Section_modify.html | 88 ++++++++--------- doc/Section_modify.txt | 91 +++++++++--------- doc/Section_perf.html | 2 +- doc/Section_perf.txt | 2 +- doc/Section_python.html | 32 +++--- doc/Section_python.txt | 32 +++--- doc/Section_tools.html | 2 +- doc/Section_tools.txt | 2 +- 22 files changed, 510 insertions(+), 404 deletions(-) diff --git a/doc/Manual.html b/doc/Manual.html index bb6be917ce..27fd5eb36f 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -122,49 +122,67 @@ it gives quick access to documentation for all LAMMPS commands.
    3.5 Commands listed alphabetically
    +
  • Packages + + +
  • Using accelerated CPU and GPU styles + +
  • How-to discussions -
      4.1 Restarting a simulation +
    • Example problems @@ -174,45 +192,63 @@ it gives quick access to documentation for all LAMMPS commands.
    • Modifying & extending LAMMPS +
    • Python interface -
        9.1 Extending Python with a serial version of LAMMPS + -
      • Using accelerated CPU and GPU styles - -
      • Errors -
          11.1 Common problems +
        • Future and history -
            12.1 Coming attractions + @@ -305,6 +341,40 @@ it gives quick access to documentation for all LAMMPS commands. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/Manual.txt b/doc/Manual.txt index f3d15998ce..1a8107aee2 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -97,52 +97,70 @@ it gives quick access to documentation for all LAMMPS commands. 3.3 "Input script structure"_3_3 :b 3.4 "Commands listed by category"_3_4 :b 3.5 "Commands listed alphabetically"_3_5 :ule,b +"Packages"_Section_packages.html :l + 4.1 "Standard packages"_3_1 :ulb,b + 4.2 "User packages"_3_2 :ule,b +"Using accelerated CPU and GPU styles"_Section_accelerate.html :l + 5.1 "OPT package"_10_1 :ulb,b + 5.2 "USER-OMP package"_10_2 :b + 5.3 "GPU package"_10_3 :b + 5.4 "USER-CUDA package"_10_4 :b + 5.5 "Comparison of GPU and USER-CUDA packages"_10_5 :ule,b "How-to discussions"_Section_howto.html :l - 4.1 "Restarting a simulation"_4_1 :ulb,b - 4.2 "2d simulations"_4_2 :b - 4.3 "CHARMM and AMBER force fields"_4_3 :b - 4.4 "Running multiple simulations from one input script"_4_4 :b - 4.5 "Multi-replica simulations"_4_5 :b - 4.6 "Granular models"_4_6 :b - 4.7 "TIP3P water model"_4_7 :b - 4.8 "TIP4P water model"_4_8 :b - 4.9 "SPC water model"_4_9 :b - 4.10 "Coupling LAMMPS to other codes"_4_10 :b - 4.11 "Visualizing LAMMPS snapshots"_4_11 :b - 4.12 "Triclinic (non-orthogonal) simulation boxes"_4_12 :b - 4.13 "NEMD simulations"_4_13 :b - 4.14 "Extended spherical and aspherical particles"_4_14 :b - 4.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_4_15 :b - 4.16 "Thermostatting, barostatting, and compute temperature"_4_16 :b - 4.17 "Walls"_4_17 :b - 4.18 "Elastic constants"_4_18 :b - 4.19 "Library interface to LAMMPS"_4_19 :b - 4.20 "Calculating thermal conductivity"_4_20 :b - 4.21 "Calculating viscosity"_4_21 :ule,b + 6.1 "Restarting a simulation"_4_1 :ulb,b + 6.2 "2d simulations"_4_2 :b + 6.3 "CHARMM and AMBER force fields"_4_3 :b + 6.4 "Running multiple simulations from one input script"_4_4 :b + 6.5 "Multi-replica simulations"_4_5 :b + 6.6 "Granular models"_4_6 :b + 6.7 "TIP3P water model"_4_7 :b + 6.8 "TIP4P water model"_4_8 :b + 6.9 "SPC water model"_4_9 :b + 6.10 "Coupling LAMMPS to other codes"_4_10 :b + 6.11 "Visualizing LAMMPS snapshots"_4_11 :b + 6.12 "Triclinic (non-orthogonal) simulation boxes"_4_12 :b + 6.13 "NEMD simulations"_4_13 :b + 6.14 "Extended spherical and aspherical particles"_4_14 :b + 6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_4_15 :b + 6.16 "Thermostatting, barostatting, and compute temperature"_4_16 :b + 6.17 "Walls"_4_17 :b + 6.18 "Elastic constants"_4_18 :b + 6.19 "Library interface to LAMMPS"_4_19 :b + 6.20 "Calculating thermal conductivity"_4_20 :b + 6.21 "Calculating viscosity"_4_21 :ule,b "Example problems"_Section_example.html :l "Performance & scalability"_Section_perf.html :l "Additional tools"_Section_tools.html :l "Modifying & extending LAMMPS"_Section_modify.html :l + 10.1 "Atom styles"_10_1 :ulb,b + 10.2 "Bond, angle, dihedral, improper potentials"_10_2 :b + 10.3 "Compute styles"_10_3 :b + 10.4 "Dump styles"_10_4 :b + 10.5 "Dump custom output options"_10_5 :b + 10.6 "Fix styles"_10_6 :b + 10.7 "Input script commands"_10_7 :b + 10.8 "Kspace computations"_10_8 :b + 10.9 "Minimization styles"_10_9 :b + 10.10 "Pairwise potentials"_10_10 :b + 10.11 "Region styles"_10_11 :b + 10.12 "Thermodynamic output options"_10_12 :b + 10.13 "Variable options"_10_13 :b + 10.14 "Submitting new features for inclusion in LAMMPS"_10_14 :ule,b "Python interface"_Section_python.html :l - 9.1 "Extending Python with a serial version of LAMMPS"_9_1 :ulb,b - 9.2 "Creating a shared MPI library"_9_2 :b - 9.3 "Extending Python with a parallel version of LAMMPS"_9_3 :b - 9.4 "Extending Python with MPI"_9_4 :b - 9.5 "Testing the Python-LAMMPS interface"_9_5 :b - 9.6 "Using LAMMPS from Python"_9_6 :b - 9.7 "Example Python scripts that use LAMMPS"_9_7 :ule,b -"Using accelerated CPU and GPU styles"_Section_accelerate.html :l - 10.1 "OPT package"_10_1 :ulb,b - 10.2 "GPU package"_10_2 :b - 10.3 "USER-CUDA package"_10_3 :b - 10.4 "Comparison of GPU and USER-CUDA packages"_10_4 :ule,b + 11.1 "Extending Python with a serial version of LAMMPS"_9_1 :ulb,b + 11.2 "Creating a shared MPI library"_9_2 :b + 11.3 "Extending Python with a parallel version of LAMMPS"_9_3 :b + 11.4 "Extending Python with MPI"_9_4 :b + 11.5 "Testing the Python-LAMMPS interface"_9_5 :b + 11.6 "Using LAMMPS from Python"_9_6 :b + 11.7 "Example Python scripts that use LAMMPS"_9_7 :ule,b "Errors"_Section_errors.html :l - 11.1 "Common problems"_11_1 :ulb,b - 11.2 "Reporting bugs"_11_2 :b - 11.3 "Error & warning messages"_11_3 :ule,b + 12.1 "Common problems"_11_1 :ulb,b + 12.2 "Reporting bugs"_11_2 :b + 12.3 "Error & warning messages"_11_3 :ule,b "Future and history"_Section_history.html :l - 12.1 "Coming attractions"_12_1 :ulb,b - 12.2 "Past versions"_12_2 :ule,b + 13.1 "Coming attractions"_12_1 :ulb,b + 13.2 "Past versions"_12_2 :ule,b :ole :link(1_1,Section_intro.html#1_1) @@ -166,46 +184,65 @@ it gives quick access to documentation for all LAMMPS commands. :link(3_4,Section_commands.html#3_4) :link(3_5,Section_commands.html#3_5) -:link(4_1,Section_howto.html#4_1) -:link(4_2,Section_howto.html#4_2) -:link(4_3,Section_howto.html#4_3) -:link(4_4,Section_howto.html#4_4) -:link(4_5,Section_howto.html#4_5) -:link(4_6,Section_howto.html#4_6) -:link(4_7,Section_howto.html#4_7) -:link(4_8,Section_howto.html#4_8) -:link(4_9,Section_howto.html#4_9) -:link(4_10,Section_howto.html#4_10) -:link(4_11,Section_howto.html#4_11) -:link(4_12,Section_howto.html#4_12) -:link(4_13,Section_howto.html#4_13) -:link(4_14,Section_howto.html#4_14) -:link(4_15,Section_howto.html#4_15) -:link(4_16,Section_howto.html#4_16) -:link(4_17,Section_howto.html#4_17) -:link(4_18,Section_howto.html#4_18) -:link(4_19,Section_howto.html#4_19) -:link(4_20,Section_howto.html#4_20) -:link(4_21,Section_howto.html#4_21) +:link(4_1,Section_commands.html#4_1) +:link(4_2,Section_commands.html#4_2) -:link(9_1,Section_python.html#9_1) -:link(9_2,Section_python.html#9_2) -:link(9_3,Section_python.html#9_3) -:link(9_4,Section_python.html#9_4) -:link(9_5,Section_python.html#9_5) -:link(9_6,Section_python.html#9_6) -:link(9_7,Section_python.html#9_7) +:link(5_1,Section_commands.html#4_1) +:link(5_2,Section_commands.html#4_2) +:link(5_3,Section_commands.html#4_2) +:link(5_4,Section_commands.html#4_2) +:link(5_5,Section_commands.html#4_2) -:link(10_1,Section_accelerate.html#10_1) -:link(10_2,Section_accelerate.html#10_2) -:link(10_3,Section_accelerate.html#10_3) -:link(10_4,Section_accelerate.html#10_4) +:link(6_1,Section_howto.html#4_1) +:link(6_2,Section_howto.html#4_2) +:link(6_3,Section_howto.html#4_3) +:link(6_4,Section_howto.html#4_4) +:link(6_5,Section_howto.html#4_5) +:link(6_6,Section_howto.html#4_6) +:link(6_7,Section_howto.html#4_7) +:link(6_8,Section_howto.html#4_8) +:link(6_9,Section_howto.html#4_9) +:link(6_10,Section_howto.html#6_10) +:link(6_11,Section_howto.html#6_11) +:link(6_12,Section_howto.html#4_12) +:link(6_13,Section_howto.html#4_13) +:link(6_14,Section_howto.html#4_14) +:link(6_15,Section_howto.html#4_15) +:link(6_16,Section_howto.html#4_16) +:link(6_17,Section_howto.html#4_17) +:link(6_18,Section_howto.html#4_18) +:link(6_19,Section_howto.html#4_19) +:link(6_20,Section_howto.html#4_20) +:link(6_21,Section_howto.html#4_21) -:link(11_1,Section_errors.html#11_1) -:link(11_2,Section_errors.html#11_2) -:link(11_3,Section_errors.html#11_3) +:link(10_1,Section_howto.html#4_1) +:link(10_2,Section_howto.html#4_2) +:link(10_3,Section_howto.html#4_3) +:link(10_4,Section_howto.html#4_4) +:link(10_5,Section_howto.html#4_5) +:link(10_6,Section_howto.html#4_6) +:link(10_7,Section_howto.html#4_7) +:link(10_8,Section_howto.html#4_8) +:link(10_9,Section_howto.html#4_9) +:link(10_10,Section_howto.html#10_10) +:link(10_11,Section_howto.html#10_11) +:link(10_12,Section_howto.html#4_12) +:link(10_13,Section_howto.html#4_13) +:link(10_14,Section_howto.html#4_14) -:link(12_1,Section_history.html#12_1) -:link(12_2,Section_history.html#12_2) +:link(11_1,Section_python.html#9_1) +:link(11_2,Section_python.html#9_2) +:link(11_3,Section_python.html#9_3) +:link(11_4,Section_python.html#9_4) +:link(11_5,Section_python.html#9_5) +:link(11_6,Section_python.html#9_6) +:link(11_7,Section_python.html#9_7) + +:link(12_1,Section_errors.html#11_1) +:link(12_2,Section_errors.html#11_2) +:link(12_3,Section_errors.html#11_3) + +:link(13_1,Section_history.html#12_1) +:link(13_2,Section_history.html#12_2) diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html index 3cee8b43ab..4e279faf23 100644 --- a/doc/Section_accelerate.html +++ b/doc/Section_accelerate.html @@ -1,6 +1,6 @@ -
            Previous Section - LAMMPS WWW Site - -LAMMPS Documentation - LAMMPS Commands - Next +
            Previous Section - LAMMPS WWW Site - +LAMMPS Documentation - LAMMPS Commands - Next Section
            @@ -11,7 +11,7 @@ Section
            -

            10. Using accelerated CPU and GPU styles +

            5. Using accelerated CPU and GPU styles

            Accelerated versions of various pair_style, fixes, computes, and other commands have @@ -73,17 +73,17 @@ and kspace sections.

            The final section compares and contrasts the GPU and USER-CUDA packages, since they are both designed to use NVIDIA GPU hardware.

            -10.1 OPT package
            -10.2 USER-OMP package
            -10.3 GPU package
            -10.4 USER-CUDA package
            -10.5 Comparison of GPU and USER-CUDA packages
            +5.1 OPT package
            +5.2 USER-OMP package
            +5.3 GPU package
            +5.4 USER-CUDA package
            +5.5 Comparison of GPU and USER-CUDA packages


            -

            10.1 OPT package +

            5.1 OPT package

            The OPT package was developed by James Fischer (High Performance Technologies), David Richie, and Vincent Natoli (Stone Ridge @@ -112,7 +112,7 @@ to 20% savings.


            -

            10.2 USER-OMP package +

            5.2 USER-OMP package

            This section will be written when the USER-OMP package is released in main LAMMPS. @@ -121,7 +121,7 @@ in main LAMMPS.


            -

            10.3 GPU package +

            5.3 GPU package

            The GPU package was developed by Mike Brown at ORNL. It provides GPU versions of several pair styles and for long-range Coulombics via the @@ -263,7 +263,7 @@ requires that your GPU card support double precision.


            -

            10.4 USER-CUDA package +

            5.4 USER-CUDA package

            The USER-CUDA package was developed by Christian Trott at U Technology Ilmenau in Germany. It provides NVIDIA GPU versions of many pair @@ -396,7 +396,7 @@ occurs, the faster your simulation will run.


            -

            10.5 Comparison of GPU and USER-CUDA packages +

            5.5 Comparison of GPU and USER-CUDA packages

            Both the GPU and USER-CUDA packages accelerate a LAMMPS calculation using NVIDIA hardware, but they do it in different ways. diff --git a/doc/Section_accelerate.txt b/doc/Section_accelerate.txt index f18745e31f..0983c8d627 100644 --- a/doc/Section_accelerate.txt +++ b/doc/Section_accelerate.txt @@ -1,6 +1,6 @@ -"Previous Section"_Section_python.html - "LAMMPS WWW Site"_lws - +"Previous Section"_Section_packages.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next -Section"_Section_errors.html :c +Section"_Section_howto.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) @@ -8,7 +8,7 @@ Section"_Section_errors.html :c :line -10. Using accelerated CPU and GPU styles :h3 +5. Using accelerated CPU and GPU styles :h3 Accelerated versions of various "pair_style"_pair_style.html, "fixes"_fix.html, "computes"_compute.html, and other commands have @@ -70,16 +70,16 @@ speed-ups you can expect :ul The final section compares and contrasts the GPU and USER-CUDA packages, since they are both designed to use NVIDIA GPU hardware. -10.1 "OPT package"_#10_1 -10.2 "USER-OMP package"_#10_2 -10.3 "GPU package"_#10_3 -10.4 "USER-CUDA package"_#10_4 -10.5 "Comparison of GPU and USER-CUDA packages"_#10_4 :all(b) +5.1 "OPT package"_#5_1 +5.2 "USER-OMP package"_#5_2 +5.3 "GPU package"_#5_3 +5.4 "USER-CUDA package"_#5_4 +5.5 "Comparison of GPU and USER-CUDA packages"_#5_4 :all(b) :line :line -10.1 OPT package :h4,link(10_1) +5.1 OPT package :h4,link(5_1) The OPT package was developed by James Fischer (High Performance Technologies), David Richie, and Vincent Natoli (Stone Ridge @@ -107,7 +107,7 @@ to 20% savings. :line :line -10.2 USER-OMP package :h4,link(10_2) +5.2 USER-OMP package :h4,link(5_2) This section will be written when the USER-OMP package is released in main LAMMPS. @@ -115,7 +115,7 @@ in main LAMMPS. :line :line -10.3 GPU package :h4,link(10_3) +5.3 GPU package :h4,link(5_3) The GPU package was developed by Mike Brown at ORNL. It provides GPU versions of several pair styles and for long-range Coulombics via the @@ -256,7 +256,7 @@ requires that your GPU card support double precision. :line :line -10.4 USER-CUDA package :h4,link(10_4) +5.4 USER-CUDA package :h4,link(5_4) The USER-CUDA package was developed by Christian Trott at U Technology Ilmenau in Germany. It provides NVIDIA GPU versions of many pair @@ -388,7 +388,7 @@ occurs, the faster your simulation will run. :line :line -10.5 Comparison of GPU and USER-CUDA packages :h4,link(10_5) +5.5 Comparison of GPU and USER-CUDA packages :h4,link(5_5) Both the GPU and USER-CUDA packages accelerate a LAMMPS calculation using NVIDIA hardware, but they do it in different ways. diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 3f364a22b9..01684f69f4 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -1,5 +1,5 @@ -

            Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section +
            Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section
            diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 05885633e3..7359b43526 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_start.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_howto.html :c +"Previous Section"_Section_start.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_packages.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) diff --git a/doc/Section_errors.html b/doc/Section_errors.html index 5ded01db43..46ac228d1c 100644 --- a/doc/Section_errors.html +++ b/doc/Section_errors.html @@ -11,18 +11,18 @@ Section
            -

            11. Errors +

            12. Errors

            This section describes the various kinds of errors you can encounter when using LAMMPS.

            -11.1 Common problems
            -11.2 Reporting bugs
            -11.3 Error & warning messages
            +12.1 Common problems
            +12.2 Reporting bugs
            +12.3 Error & warning messages

            -

            11.1 Common problems +

            12.1 Common problems

            If two LAMMPS runs do not produce the same answer on different machines or different numbers of processors, this is typically not a @@ -81,7 +81,7 @@ decide if the WARNING is important or not. A WARNING message that is generated in the middle of a run is only printed to the screen, not to the logfile, to avoid cluttering up thermodynamic output. If LAMMPS crashes or hangs without spitting out an error message first then it -could be a bug (see this section) or one of the following +could be a bug (see this section) or one of the following cases:

            LAMMPS runs in the available memory a processor allows to be @@ -112,7 +112,7 @@ buffering or boost the sizes of messages that can be buffered.


            -

            11.2 Reporting bugs +

            12.2 Reporting bugs

            If you are confident that you have found a bug in LAMMPS, follow these steps. @@ -142,7 +142,7 @@ causing the problem.


            -

            11.3 Error & warning messages +

            12.3 Error & warning messages

            These are two alphabetic lists of the ERROR and WARNING messages LAMMPS prints out and the reason why. If the diff --git a/doc/Section_errors.txt b/doc/Section_errors.txt index 740798f63f..b080dc17c2 100644 --- a/doc/Section_errors.txt +++ b/doc/Section_errors.txt @@ -8,18 +8,18 @@ Section"_Section_history.html :c :line -11. Errors :h3 +12. Errors :h3 This section describes the various kinds of errors you can encounter when using LAMMPS. -11.1 "Common problems"_#11_1 -11.2 "Reporting bugs"_#11_2 -11.3 "Error & warning messages"_#11_3 :all(b) +12.1 "Common problems"_#12_1 +12.2 "Reporting bugs"_#12_2 +12.3 "Error & warning messages"_#12_3 :all(b) :line -11.1 Common problems :link(11_1),h4 +12.1 Common problems :link(12_1),h4 If two LAMMPS runs do not produce the same answer on different machines or different numbers of processors, this is typically not a @@ -78,7 +78,7 @@ decide if the WARNING is important or not. A WARNING message that is generated in the middle of a run is only printed to the screen, not to the logfile, to avoid cluttering up thermodynamic output. If LAMMPS crashes or hangs without spitting out an error message first then it -could be a bug (see "this section"_#11_2) or one of the following +could be a bug (see "this section"_#12_2) or one of the following cases: LAMMPS runs in the available memory a processor allows to be @@ -109,7 +109,7 @@ buffering or boost the sizes of messages that can be buffered. :line -11.2 Reporting bugs :link(11_2),h4 +12.2 Reporting bugs :link(12_2),h4 If you are confident that you have found a bug in LAMMPS, follow these steps. @@ -139,7 +139,7 @@ As a last resort, you can send an email directly to the :line -11.3 Error & warning messages :h4,link(11_3) +12.3 Error & warning messages :h4,link(12_3) These are two alphabetic lists of the "ERROR"_#error and "WARNING"_#warn messages LAMMPS prints out and the reason why. If the diff --git a/doc/Section_example.html b/doc/Section_example.html index 5e32f0ca3c..94e2d95d64 100644 --- a/doc/Section_example.html +++ b/doc/Section_example.html @@ -9,7 +9,7 @@


            -

            5. Example problems +

            7. Example problems

            The LAMMPS distribution includes an examples sub-directory with several sample problems. Each problem is in a sub-directory of its diff --git a/doc/Section_example.txt b/doc/Section_example.txt index 241f01f70b..947c7957c7 100644 --- a/doc/Section_example.txt +++ b/doc/Section_example.txt @@ -6,7 +6,7 @@ :line -5. Example problems :h3 +7. Example problems :h3 The LAMMPS distribution includes an examples sub-directory with several sample problems. Each problem is in a sub-directory of its diff --git a/doc/Section_history.html b/doc/Section_history.html index 399b4dc23d..ee854fc829 100644 --- a/doc/Section_history.html +++ b/doc/Section_history.html @@ -9,18 +9,18 @@


            -

            12. Future and history +

            13. Future and history

            This section lists features we are planning to add to LAMMPS, features of previous versions of LAMMPS, and features of other parallel molecular dynamics codes I've distributed.

            -12.1 Coming attractions
            -12.2 Past versions
            +13.1 Coming attractions
            +13.2 Past versions

            -

            12.1 Coming attractions +

            13.1 Coming attractions

            The current version of LAMMPS incorporates nearly all the features from previous parallel MD codes developed at Sandia. These include @@ -49,7 +49,7 @@ page on the LAMMPS WWW site for more details.


          -

          12.2 Past versions +

          13.2 Past versions

          LAMMPS development began in the mid 1990s under a cooperative research & development agreement (CRADA) between two DOE labs (Sandia and LLNL) diff --git a/doc/Section_history.txt b/doc/Section_history.txt index f3887b7e09..ab737285f0 100644 --- a/doc/Section_history.txt +++ b/doc/Section_history.txt @@ -6,18 +6,18 @@ :line -12. Future and history :h3 +13. Future and history :h3 This section lists features we are planning to add to LAMMPS, features of previous versions of LAMMPS, and features of other parallel molecular dynamics codes I've distributed. -12.1 "Coming attractions"_#12_1 -12.2 "Past versions"_#12_2 :all(b) +13.1 "Coming attractions"_#13_1 +13.2 "Past versions"_#13_2 :all(b) :line -12.1 Coming attractions :h4,link(12_1) +13.1 Coming attractions :h4,link(13_1) The current version of LAMMPS incorporates nearly all the features from previous parallel MD codes developed at Sandia. These include @@ -46,7 +46,7 @@ Direct Simulation Monte Carlo - DSMC :ul :line -12.2 Past versions :h4,link(12_2) +13.2 Past versions :h4,link(13_2) LAMMPS development began in the mid 1990s under a cooperative research & development agreement (CRADA) between two DOE labs (Sandia and LLNL) diff --git a/doc/Section_howto.html b/doc/Section_howto.html index 1bc6d97ec4..4b68d34a7c 100644 --- a/doc/Section_howto.html +++ b/doc/Section_howto.html @@ -1,5 +1,5 @@ -

          Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section +
          Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section
          @@ -9,32 +9,32 @@
          -

          4. How-to discussions +

          6. How-to discussions

          The following sections describe how to use various options within LAMMPS.

          -4.1 Restarting a simulation
          -4.2 2d simulations
          -4.3 CHARMM, AMBER, and DREIDING force fields
          -4.4 Running multiple simulations from one input script
          -4.5 Multi-replica simulations
          -4.6 Granular models
          -4.7 TIP3P water model
          -4.8 TIP4P water model
          -4.9 SPC water model
          -4.10 Coupling LAMMPS to other codes
          -4.11 Visualizing LAMMPS snapshots
          -4.12 Triclinic (non-orthogonal) simulation boxes
          -4.13 NEMD simulations
          -4.14 Extended spherical and aspherical particles
          -4.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables)
          -4.16 Thermostatting, barostatting and computing temperature
          -4.17 Walls
          -4.18 Elastic constants
          -4.19 Library interface to LAMMPS
          -4.20 Calculating thermal conductivity
          -4.21 Calculating viscosity
          +6.1 Restarting a simulation
          +6.2 2d simulations
          +6.3 CHARMM, AMBER, and DREIDING force fields
          +6.4 Running multiple simulations from one input script
          +6.5 Multi-replica simulations
          +6.6 Granular models
          +6.7 TIP3P water model
          +6.8 TIP4P water model
          +6.9 SPC water model
          +6.10 Coupling LAMMPS to other codes
          +6.11 Visualizing LAMMPS snapshots
          +6.12 Triclinic (non-orthogonal) simulation boxes
          +6.13 NEMD simulations
          +6.14 Extended spherical and aspherical particles
          +6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables)
          +6.16 Thermostatting, barostatting and computing temperature
          +6.17 Walls
          +6.18 Elastic constants
          +6.19 Library interface to LAMMPS
          +6.20 Calculating thermal conductivity
          +6.21 Calculating viscosity

          The example input scripts included in the LAMMPS distribution and highlighted in this section also show how to @@ -42,7 +42,7 @@ setup and run various kinds of simulations.


          -

          4.1 Restarting a simulation +

          6.1 Restarting a simulation

          There are 3 ways to continue a long LAMMPS simulation. Multiple run commands can be used in the same input script. Each @@ -134,7 +134,7 @@ but not in data files.


          -

          4.2 2d simulations +

          6.2 2d simulations

          Use the dimension command to specify a 2d simulation.

          @@ -169,7 +169,7 @@ the same as in 3d.


          -

          4.3 CHARMM, AMBER, and DREIDING force fields +

          6.3 CHARMM, AMBER, and DREIDING force fields

          A force field has 2 parts: the formulas that define it and the coefficients used for a particular system. Here we only discuss @@ -246,7 +246,7 @@ documentation for the formula it computes.


        -

        4.4 Running multiple simulations from one input script +

        6.4 Running multiple simulations from one input script

        This can be done in several ways. See the documentation for individual commands for more details on how these examples work. @@ -334,7 +334,7 @@ the 4th simulation, and so forth, until all 8 were completed.


        -

        4.5 Multi-replica simulations +

        6.5 Multi-replica simulations

        Several commands in LAMMPS run mutli-replica simulations, meaning that multiple instances (replicas) of your simulation are run @@ -381,7 +381,7 @@ physical processors.


        -

        4.6 Granular models +

        6.6 Granular models

        Granular system are composed of spherical particles with a diameter, as opposed to point particles. This means they have an angular @@ -398,7 +398,7 @@ the following commands:

        -

        calculates rotational kinetic energy which can be output with +

        calculates rotational kinetic energy which can be output with thermodynamic info.

        Use one of these 3 pair potentials, which compute forces and torques @@ -426,7 +426,7 @@ computations between frozen atoms by using this command:


      -

      4.7 TIP3P water model +

      6.7 TIP3P water model

      The TIP3P water model as implemented in CHARMM (MacKerell) specifies a 3-site rigid water molecule with @@ -486,7 +486,7 @@ models.


      -

      4.8 TIP4P water model +

      6.8 TIP4P water model

      The four-point TIP4P rigid water model extends the traditional three-point TIP3P model by adding an additional site, usually @@ -545,7 +545,7 @@ models.


      -

      4.9 SPC water model +

      6.9 SPC water model

      The SPC water model specifies a 3-site rigid water molecule with charges and Lennard-Jones parameters assigned to each of the 3 atoms. @@ -590,7 +590,7 @@ models.


      -

      4.10 Coupling LAMMPS to other codes +

      6.10 Coupling LAMMPS to other codes

      LAMMPS is designed to allow it to be coupled to other codes. For example, a quantum mechanics code might compute forces on a subset of @@ -673,7 +673,7 @@ the Python wrapper provided with LAMMPS that operates through the LAMMPS library interface.

      The files src/library.cpp and library.h contain the C-style interface -to LAMMPS. See this section of the manual +to LAMMPS. See this section of the manual for a description of the interface and how to extend it for your needs.

      @@ -690,7 +690,7 @@ instances of LAMMPS to perform different calculations.


      -

      4.11 Visualizing LAMMPS snapshots +

      6.11 Visualizing LAMMPS snapshots

      LAMMPS itself does not do visualization, but snapshots from LAMMPS simulations can be visualized (and analyzed) in a variety of ways. @@ -749,7 +749,7 @@ See the dump command for more information on XTC files


      -

      4.12 Triclinic (non-orthogonal) simulation boxes +

      6.12 Triclinic (non-orthogonal) simulation boxes

      By default, LAMMPS uses an orthogonal simulation box to encompass the particles. The boundary command sets the boundary @@ -882,7 +882,7 @@ on non-equilibrium MD (NEMD) simulations.


      -

      4.13 NEMD simulations +

      6.13 NEMD simulations

      Non-equilibrium molecular dynamics or NEMD simulations are typically used to measure a fluid's rheological properties such as viscosity. @@ -920,7 +920,7 @@ profile consistent with the applied shear strain rate.


      -

      4.14 Extended spherical and aspherical particles +

      6.14 Extended spherical and aspherical particles

      Typical MD models treat atoms or particles as point masses. Sometimes, however, it is desirable to have a model with finite-size @@ -1100,7 +1100,7 @@ particles are point masses.


      -

      4.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) +

      6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables)

      There are four basic kinds of LAMMPS output:

      @@ -1394,7 +1394,7 @@ vector input could be a column of an array.
      -

      4.16 Thermostatting, barostatting, and computing temperature +

      6.16 Thermostatting, barostatting, and computing temperature

      Thermostatting means controlling the temperature of particles in an MD simulation. Barostatting means controlling the pressure. Since the @@ -1455,7 +1455,7 @@ thermostatting can be invoked via the dpd/tstat pair style:

      Fix nvt only thermostats the translational velocity of particles. Fix nvt/sllod also does this, except that it subtracts out a velocity bias due to a deforming box and -integrates the SLLOD equations of motion. See the NEMD +integrates the SLLOD equations of motion. See the NEMD simulations section of this page for further details. Fix nvt/sphere and fix nvt/asphere thermostat not only translation @@ -1545,7 +1545,7 @@ thermodynamic output.


      -

      4.17 Walls +

      6.17 Walls

      Walls in an MD simulation are typically used to bound particle motion, i.e. to serve as a boundary condition. @@ -1619,7 +1619,7 @@ frictional walls, as well as triangulated surfaces.


      -

      4.18 Elastic constants +

      6.18 Elastic constants

      Elastic constants characterize the stiffness of a material. The formal definition is provided by the linear relation that holds between the @@ -1655,11 +1655,11 @@ converge and requires careful post-processing (Shinoda)


      -

      4.19 Library interface to LAMMPS +

      6.19 Library interface to LAMMPS

      As described in this section, LAMMPS can be built as a library, so that it can be called by another code, used in -a coupled manner with other codes, or driven +a coupled manner with other codes, or driven through a Python interface.

      All of these methodologies use a C-style interface to LAMMPS that is @@ -1735,10 +1735,10 @@ grab data from LAMMPS, change it, and put it back into LAMMPS.


      -

      4.20 Calculating thermal conductivity +

      6.20 Calculating thermal conductivity

      The thermal conductivity kappa of a material can be measured in at -least 3 ways using various options in LAMMPS. (See this +least 3 ways using various options in LAMMPS. (See this section of the manual for an analogous discussion for viscosity). The thermal conducitivity tensor kappa is a measure of the propensity of a material to transmit heat energy in a @@ -1755,7 +1755,7 @@ scalar.

      The first method is to setup two thermostatted regions at opposite ends of a simulation box, or one in the middle and one at the end of a periodic box. By holding the two regions at different temperatures -with a thermostatting fix, the energy added +with a thermostatting fix, the energy added to the hot region should equal the energy subtracted from the cold region and be proportional to the heat flux moving between the regions. See the paper by Ikeshoji and Hafskjold for @@ -1800,10 +1800,10 @@ formalism.


      -

      4.21 Calculating viscosity +

      6.21 Calculating viscosity

      The shear viscosity eta of a fluid can be measured in at least 3 ways -using various options in LAMMPS. (See this +using various options in LAMMPS. (See this section of the manual for an analogous discussion for thermal conductivity). Eta is a measure of the propensity of a fluid to transmit momentum in a direction @@ -1829,7 +1829,7 @@ y-direction of the Vx component of fluid motion or grad(Vstream) = dVx/dy. In this case, the Pxy off-diagonal component of the pressure or stress tensor, as calculated by the compute pressure command, can also be monitored, which -is the J term in the equation above. See this +is the J term in the equation above. See this section of the manual for details on NEMD simulations.

      diff --git a/doc/Section_howto.txt b/doc/Section_howto.txt index b6337c7de3..ead4d60559 100644 --- a/doc/Section_howto.txt +++ b/doc/Section_howto.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_commands.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_example.html :c +"Previous Section"_Section_accelerate.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_example.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) @@ -6,32 +6,32 @@ :line -4. How-to discussions :h3 +6. How-to discussions :h3 The following sections describe how to use various options within LAMMPS. -4.1 "Restarting a simulation"_#4_1 -4.2 "2d simulations"_#4_2 -4.3 "CHARMM, AMBER, and DREIDING force fields"_#4_3 -4.4 "Running multiple simulations from one input script"_#4_4 -4.5 "Multi-replica simulations"_#4_5 -4.6 "Granular models"_#4_6 -4.7 "TIP3P water model"_#4_7 -4.8 "TIP4P water model"_#4_8 -4.9 "SPC water model"_#4_9 -4.10 "Coupling LAMMPS to other codes"_#4_10 -4.11 "Visualizing LAMMPS snapshots"_#4_11 -4.12 "Triclinic (non-orthogonal) simulation boxes"_#4_12 -4.13 "NEMD simulations"_#4_13 -4.14 "Extended spherical and aspherical particles"_#4_14 -4.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_#4_15 -4.16 "Thermostatting, barostatting and computing temperature"_#4_16 -4.17 "Walls"_#4_17 -4.18 "Elastic constants"_#4_18 -4.19 "Library interface to LAMMPS"_#4_19 -4.20 "Calculating thermal conductivity"_#4_20 -4.21 "Calculating viscosity"_#4_21 :all(b) +6.1 "Restarting a simulation"_#6_1 +6.2 "2d simulations"_#6_2 +6.3 "CHARMM, AMBER, and DREIDING force fields"_#6_3 +6.4 "Running multiple simulations from one input script"_#6_4 +6.5 "Multi-replica simulations"_#6_5 +6.6 "Granular models"_#6_6 +6.7 "TIP3P water model"_#6_7 +6.8 "TIP4P water model"_#6_8 +6.9 "SPC water model"_#6_9 +6.10 "Coupling LAMMPS to other codes"_#6_10 +6.11 "Visualizing LAMMPS snapshots"_#6_11 +6.12 "Triclinic (non-orthogonal) simulation boxes"_#6_12 +6.13 "NEMD simulations"_#6_13 +6.14 "Extended spherical and aspherical particles"_#6_14 +6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_#6_15 +6.16 "Thermostatting, barostatting and computing temperature"_#6_16 +6.17 "Walls"_#6_17 +6.18 "Elastic constants"_#6_18 +6.19 "Library interface to LAMMPS"_#6_19 +6.20 "Calculating thermal conductivity"_#6_20 +6.21 "Calculating viscosity"_#6_21 :all(b) The example input scripts included in the LAMMPS distribution and highlighted in "this section"_Section_example.html also show how to @@ -39,7 +39,7 @@ setup and run various kinds of simulations. :line -4.1 Restarting a simulation :link(4_1),h4 +6.1 Restarting a simulation :link(6_1),h4 There are 3 ways to continue a long LAMMPS simulation. Multiple "run"_run.html commands can be used in the same input script. Each @@ -131,7 +131,7 @@ but not in data files. :line -4.2 2d simulations :link(4_2),h4 +6.2 2d simulations :link(6_2),h4 Use the "dimension"_dimension.html command to specify a 2d simulation. @@ -166,7 +166,7 @@ the same as in 3d. :line -4.3 CHARMM, AMBER, and DREIDING force fields :link(4_3),h4 +6.3 CHARMM, AMBER, and DREIDING force fields :link(6_3),h4 A force field has 2 parts: the formulas that define it and the coefficients used for a particular system. Here we only discuss @@ -242,7 +242,7 @@ documentation for the formula it computes. :line -4.4 Running multiple simulations from one input script :link(4_4),h4 +6.4 Running multiple simulations from one input script :link(6_4),h4 This can be done in several ways. See the documentation for individual commands for more details on how these examples work. @@ -330,7 +330,7 @@ the 4th simulation, and so forth, until all 8 were completed. :line -4.5 Multi-replica simulations :link(4_5),h4 +6.5 Multi-replica simulations :link(6_5),h4 Several commands in LAMMPS run mutli-replica simulations, meaning that multiple instances (replicas) of your simulation are run @@ -377,7 +377,7 @@ physical processors. :line -4.6 Granular models :link(4_6),h4 +6.6 Granular models :link(6_6),h4 Granular system are composed of spherical particles with a diameter, as opposed to point particles. This means they have an angular @@ -395,7 +395,7 @@ This compute "compute erotate/sphere"_compute_erotate_sphere.html :ul calculates rotational kinetic energy which can be "output with -thermodynamic info"_Section_howto.html#4_15. +thermodynamic info"_Section_howto.html#6_15. Use one of these 3 pair potentials, which compute forces and torques between interacting pairs of particles: @@ -422,7 +422,7 @@ computations between frozen atoms by using this command: :line -4.7 TIP3P water model :link(4_7),h4 +6.7 TIP3P water model :link(6_7),h4 The TIP3P water model as implemented in CHARMM "(MacKerell)"_#MacKerell specifies a 3-site rigid water molecule with @@ -482,7 +482,7 @@ models"_http://en.wikipedia.org/wiki/Water_model. :line -4.8 TIP4P water model :link(4_8),h4 +6.8 TIP4P water model :link(6_8),h4 The four-point TIP4P rigid water model extends the traditional three-point TIP3P model by adding an additional site, usually @@ -541,7 +541,7 @@ models"_http://en.wikipedia.org/wiki/Water_model. :line -4.9 SPC water model :link(4_9),h4 +6.9 SPC water model :link(6_9),h4 The SPC water model specifies a 3-site rigid water molecule with charges and Lennard-Jones parameters assigned to each of the 3 atoms. @@ -586,7 +586,7 @@ models"_http://en.wikipedia.org/wiki/Water_model. :line -4.10 Coupling LAMMPS to other codes :link(4_10),h4 +6.10 Coupling LAMMPS to other codes :link(6_10),h4 LAMMPS is designed to allow it to be coupled to other codes. For example, a quantum mechanics code might compute forces on a subset of @@ -668,7 +668,7 @@ the Python wrapper provided with LAMMPS that operates through the LAMMPS library interface. The files src/library.cpp and library.h contain the C-style interface -to LAMMPS. See "this section"_Section_howto.html#4_19 of the manual +to LAMMPS. See "this section"_Section_howto.html#6_19 of the manual for a description of the interface and how to extend it for your needs. @@ -685,7 +685,7 @@ instances of LAMMPS to perform different calculations. :line -4.11 Visualizing LAMMPS snapshots :link(4_11),h4 +6.11 Visualizing LAMMPS snapshots :link(6_11),h4 LAMMPS itself does not do visualization, but snapshots from LAMMPS simulations can be visualized (and analyzed) in a variety of ways. @@ -741,7 +741,7 @@ See the "dump"_dump.html command for more information on XTC files. :line -4.12 Triclinic (non-orthogonal) simulation boxes :link(4_12),h4 +6.12 Triclinic (non-orthogonal) simulation boxes :link(6_12),h4 By default, LAMMPS uses an orthogonal simulation box to encompass the particles. The "boundary"_boundary.html command sets the boundary @@ -874,7 +874,7 @@ on non-equilibrium MD (NEMD) simulations. :line -4.13 NEMD simulations :link(4_13),h4 +6.13 NEMD simulations :link(6_13),h4 Non-equilibrium molecular dynamics or NEMD simulations are typically used to measure a fluid's rheological properties such as viscosity. @@ -912,7 +912,7 @@ An alternative method for calculating viscosities is provided via the :line -4.14 Extended spherical and aspherical particles :link(4_14),h4 +6.14 Extended spherical and aspherical particles :link(6_14),h4 Typical MD models treat atoms or particles as point masses. Sometimes, however, it is desirable to have a model with finite-size @@ -1092,7 +1092,7 @@ particles are point masses. :line -4.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) :link(4_15),h4 +6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) :link(6_15),h4 There are four basic kinds of LAMMPS output: @@ -1382,7 +1382,7 @@ Command: Input: Output: :line -4.16 Thermostatting, barostatting, and computing temperature :link(4_16),h4 +6.16 Thermostatting, barostatting, and computing temperature :link(6_16),h4 Thermostatting means controlling the temperature of particles in an MD simulation. Barostatting means controlling the pressure. Since the @@ -1444,7 +1444,7 @@ thermostatting can be invoked via the {dpd/tstat} pair style: particles. "Fix nvt/sllod"_fix_nvt_sllod.html also does this, except that it subtracts out a velocity bias due to a deforming box and integrates the SLLOD equations of motion. See the "NEMD -simulations"_#4_13 section of this page for further details. "Fix +simulations"_#6_13 section of this page for further details. "Fix nvt/sphere"_fix_nvt_sphere.html and "fix nvt/asphere"_fix_nvt_asphere.html thermostat not only translation velocities but also rotational velocities for spherical and aspherical @@ -1533,7 +1533,7 @@ thermodynamic output. :line -4.17 Walls :link(4_17),h4 +6.17 Walls :link(6_17),h4 Walls in an MD simulation are typically used to bound particle motion, i.e. to serve as a boundary condition. @@ -1607,7 +1607,7 @@ frictional walls, as well as triangulated surfaces. :line -4.18 Elastic constants :link(4_18),h4 +6.18 Elastic constants :link(6_18),h4 Elastic constants characterize the stiffness of a material. The formal definition is provided by the linear relation that holds between the @@ -1643,11 +1643,11 @@ converge and requires careful post-processing "(Shinoda)"_#Shinoda :line -4.19 Library interface to LAMMPS :link(4_19),h4 +6.19 Library interface to LAMMPS :link(6_19),h4 As described in "this section"_Section_start.html#2_4, LAMMPS can be built as a library, so that it can be called by another code, used in -a "coupled manner"_Section_howto.html#4_10 with other codes, or driven +a "coupled manner"_Section_howto.html#6_10 with other codes, or driven through a "Python interface"_Section_python.html. All of these methodologies use a C-style interface to LAMMPS that is @@ -1723,11 +1723,11 @@ grab data from LAMMPS, change it, and put it back into LAMMPS. :line -4.20 Calculating thermal conductivity :link(4_20),h4 +6.20 Calculating thermal conductivity :link(6_20),h4 The thermal conductivity kappa of a material can be measured in at least 3 ways using various options in LAMMPS. (See "this -section"_Section_howto.html#4_21 of the manual for an analogous +section"_Section_howto.html#6_21 of the manual for an analogous discussion for viscosity). The thermal conducitivity tensor kappa is a measure of the propensity of a material to transmit heat energy in a diffusive manner as given by Fourier's law @@ -1743,7 +1743,7 @@ scalar. The first method is to setup two thermostatted regions at opposite ends of a simulation box, or one in the middle and one at the end of a periodic box. By holding the two regions at different temperatures -with a "thermostatting fix"_Section_howto.html#4_13, the energy added +with a "thermostatting fix"_Section_howto.html#6_13, the energy added to the hot region should equal the energy subtracted from the cold region and be proportional to the heat flux moving between the regions. See the paper by "Ikeshoji and Hafskjold"_#Ikeshoji for @@ -1788,11 +1788,11 @@ formalism. :line -4.21 Calculating viscosity :link(4_21),h4 +6.21 Calculating viscosity :link(6_21),h4 The shear viscosity eta of a fluid can be measured in at least 3 ways using various options in LAMMPS. (See "this -section"_Section_howto.html#4_20 of the manual for an analogous +section"_Section_howto.html#6_20 of the manual for an analogous discussion for thermal conductivity). Eta is a measure of the propensity of a fluid to transmit momentum in a direction perpendicular to the direction of velocity or momentum flow. @@ -1818,7 +1818,7 @@ dVx/dy. In this case, the Pxy off-diagonal component of the pressure or stress tensor, as calculated by the "compute pressure"_compute_pressure.html command, can also be monitored, which is the J term in the equation above. See "this -section"_Section_howto.html#4_13 of the manual for details on NEMD +section"_Section_howto.html#6_13 of the manual for details on NEMD simulations. The second method is to perform a reverse non-equilibrium MD diff --git a/doc/Section_modify.html b/doc/Section_modify.html index 2c975df18f..e4b9173ddf 100644 --- a/doc/Section_modify.html +++ b/doc/Section_modify.html @@ -11,7 +11,7 @@ Section
      -

      8. Modifying & extending LAMMPS +

      10. Modifying & extending LAMMPS

      LAMMPS is designed in a modular fashion so as to be easy to modify and extend with new functionality. In fact, about 75% of its source code @@ -75,28 +75,9 @@ the executable and can be invoked with a pair_style command like the example above. Arguments like 0.1 and 3.5 can be defined and processed by your new class.

      -

      Here is a list of the new features that can be added in this way, -along with information about how to submit your features for inclusion -in the LAMMPS distribution. -

      - - -

      As illustrated by the pairwise example, these options are referred to -in the LAMMPS documentation as the "style" of a particular command. +

      As illustrated by this pairwise example, many kinds of options are +referred to in the LAMMPS documentation as the "style" of a particular +command.

      The instructions below give the header file for the base class that these styles are derived from. Public variables in that file are ones @@ -108,13 +89,9 @@ LAMMPS expects. Virtual functions that are not set to 0 are functions you can optionally define.

      Additionally, new output options can be added directly to the -thermo.cpp, dump_custom.cpp, and variable.cpp files as explained in -these sections: +thermo.cpp, dump_custom.cpp, and variable.cpp files as explained +below.

      -

      Here are additional guidelines for modifying LAMMPS and adding new @@ -136,13 +113,34 @@ command.

    • If you add something you think is truly useful and doesn't impact LAMMPS performance when it isn't used, send an email to the developers. We might be -interested in adding it to the LAMMPS distribution. +interested in adding it to the LAMMPS distribution. See further +details on this at the bottom of this page.

    +

    Here are the subsequent topics discussed below, most of which are new +features that can be added in the manner just described: +

    +10.1 Atom styles
    +10.2 Bond, angle, dihedral, improper potentials
    +10.3 Compute styles
    +10.4 Dump styles
    +10.5 Dump custom output options
    +10.6 Fix styles which include integrators, temperature and pressure control, force constraints, boundary conditions, diagnostic output, etc
    +10.7 Input script commands
    +10.8 Kspace computations
    +10.9 Minimization styles
    +10.10 Pairwise potentials
    +10.11 Region styles
    +10.12 Thermodynamic output options
    +10.13 Variable options
    +10.14 Submitting new features for inclusion in LAMMPS
    +
    -

    Atom styles +
    + +

    10.1 Atom styles

    Classes that define an atom style are derived from the Atom class. The atom style determines what quantities are associated with an atom. @@ -192,7 +190,7 @@ modify.


    -

    Bond, angle, dihedral, improper potentials +

    10.2 Bond, angle, dihedral, improper potentials

    Classes that compute molecular interactions are derived from the Bond, Angle, Dihedral, and Improper classes. New styles can be created to @@ -216,7 +214,7 @@ details.


    -

    Compute styles +

    10.3 Compute styles

    Classes that compute scalar and vector quantities like temperature and the pressure tensor, as well as classes that compute per-atom @@ -244,9 +242,9 @@ class. See compute.h for details.


    -

    Dump styles +

    10.4 Dump styles

    -

    Dump custom output options +

    10.5 Dump custom output options

    Classes that dump per-atom info to files are derived from the Dump class. To dump new quantities or in a new format, a new derived dump @@ -277,7 +275,7 @@ half-dozen or so locations where code will need to be added.


    -

    Fix styles +

    10.6 Fix styles

    In LAMMPS, a "fix" is any operation that is computed during timestepping that alters some property of the system. Essentially @@ -355,7 +353,7 @@ quantities and/or to be summed to the potential energy of the system.


    -

    Input script commands +

    10.7 Input script commands

    New commands can be added to LAMMPS input scripts by adding new classes that have a "command" method. For example, the create_atoms, @@ -377,7 +375,7 @@ needed.


    -

    Kspace computations +

    10.8 Kspace computations

    Classes that compute long-range Coulombic interactions via K-space representations (Ewald, PPPM) are derived from the KSpace class. New @@ -397,7 +395,7 @@ class. See kspace.h for details.


    -

    Minimization solvers +

    10.9 Minimization styles

    Classes that perform energy minimization derived from the Min class. New styles can be created to add new minimization algorithms to @@ -416,7 +414,7 @@ class. See min.h for details.


    -

    Pairwise potentials +

    10.10 Pairwise potentials

    Classes that compute pairwise interactions are derived from the Pair class. In LAMMPS, pairwise calculation include manybody potentials @@ -445,7 +443,7 @@ includes some optional methods to enable its use with rRESPA.


    -

    Region styles +

    10.11 Region styles

    Classes that define geometric regions are derived from the Region class. Regions are used elsewhere in LAMMPS to group atoms, delete @@ -463,7 +461,7 @@ class. See region.h for details.


    -

    Thermodynamic output options +

    10.12 Thermodynamic output options

    There is one class that computes and prints thermodynamic information to the screen and log file; see the file thermo.cpp. @@ -492,7 +490,7 @@ by adding a new keyword to the thermo command.


    -

    Variable options +

    10.13 Variable options

    There is one class that computes and stores variable information in LAMMPS; see the file variable.cpp. The value @@ -532,7 +530,9 @@ then be accessed by variables) was discussed


    -

    Submitting new features to the developers to include in LAMMPS +
    + +

    10.14 Submitting new features for inclusion in LAMMPS

    We encourage users to submit new features that they add to LAMMPS to the developers, especially if diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt index fc72b625e8..5ed8ef9219 100644 --- a/doc/Section_modify.txt +++ b/doc/Section_modify.txt @@ -8,7 +8,7 @@ Section"_Section_python.html :c :line -8. Modifying & extending LAMMPS :h3 +10. Modifying & extending LAMMPS :h3 LAMMPS is designed in a modular fashion so as to be easy to modify and extend with new functionality. In fact, about 75% of its source code @@ -72,30 +72,9 @@ the executable and can be invoked with a pair_style command like the example above. Arguments like 0.1 and 3.5 can be defined and processed by your new class. -Here is a list of the new features that can be added in this way, -along with information about how to submit your features for inclusion -in the LAMMPS distribution. - -"Atom styles"_#atom -"Bond, angle, dihedral, improper potentials"_#bond -"Compute styles"_#compute -"Dump styles"_#dump -"Dump custom output options"_#dump -"Fix styles"_#fix which include integrators, \ - temperature and pressure control, force constraints, \ - boundary conditions, diagnostic output, etc -"Input script commands"_#command -"Kspace computations"_#kspace -"Minimization solvers"_#min -"Pairwise potentials"_#pair -"Region styles"_#region -"Thermodynamic output options"_#thermo -"Variable options"_#variable :ul - -"Submitting new features to the developers to include in LAMMPS"_#package :ul - -As illustrated by the pairwise example, these options are referred to -in the LAMMPS documentation as the "style" of a particular command. +As illustrated by this pairwise example, many kinds of options are +referred to in the LAMMPS documentation as the "style" of a particular +command. The instructions below give the header file for the base class that these styles are derived from. Public variables in that file are ones @@ -107,12 +86,8 @@ LAMMPS expects. Virtual functions that are not set to 0 are functions you can optionally define. Additionally, new output options can be added directly to the -thermo.cpp, dump_custom.cpp, and variable.cpp files as explained in -these sections: - -"Dump custom output options"_#dump_custom -"Thermodynamic output options"_#thermo -"Variable options"_#variable :ul +thermo.cpp, dump_custom.cpp, and variable.cpp files as explained +below. :line @@ -135,12 +110,35 @@ command. :l If you add something you think is truly useful and doesn't impact LAMMPS performance when it isn't used, send an email to the "developers"_http://lammps.sandia.gov/authors.html. We might be -interested in adding it to the LAMMPS distribution. :l,ule +interested in adding it to the LAMMPS distribution. See further +details on this at the bottom of this page. :l,ule + +:line + +Here are the subsequent topics discussed below, most of which are new +features that can be added in the manner just described: + +10.1 "Atom styles"_#10_1 +10.2 "Bond, angle, dihedral, improper potentials"_#10_2 +10.3 "Compute styles"_#10_3 +10.4 "Dump styles"_#10_4 +10.5 "Dump custom output options"_#10_5 +10.6 "Fix styles"_#10_6 which include integrators, \ + temperature and pressure control, force constraints, \ + boundary conditions, diagnostic output, etc +10.7 "Input script commands"_10_7 +10.8 "Kspace computations"_#10_8 +10.9 "Minimization styles"_#10_9 +10.10 "Pairwise potentials"_#10_10 +10.11 "Region styles"_#10_11 +10.12 "Thermodynamic output options"_#10_12 +10.13 "Variable options"_#10_13 +10.14 "Submitting new features for inclusion in LAMMPS"_#10_14 :all(b) :line :line -Atom styles :link(atom),h4 +10.1 Atom styles :link(10_1),h4 Classes that define an atom style are derived from the Atom class. The atom style determines what quantities are associated with an atom. @@ -188,7 +186,7 @@ modify. :line -Bond, angle, dihedral, improper potentials :link(bond),h4 +10.2 Bond, angle, dihedral, improper potentials :link(10_2),h4 Classes that compute molecular interactions are derived from the Bond, Angle, Dihedral, and Improper classes. New styles can be created to @@ -210,7 +208,7 @@ single: force and energy of a single bond :tb(s=:) :line -Compute styles :link(compute),h4 +10.3 Compute styles :link(10_3),h4 Classes that compute scalar and vector quantities like temperature and the pressure tensor, as well as classes that compute per-atom @@ -236,8 +234,8 @@ memory_usage: tally memory usage :tb(s=:) :line -Dump styles :link(dump),h4 -Dump custom output options :link(dump_custom),h4 +10.4 Dump styles :link(10_4),h4 +10.5 Dump custom output options :link(10_5),h4 Classes that dump per-atom info to files are derived from the Dump class. To dump new quantities or in a new format, a new derived dump @@ -266,7 +264,7 @@ half-dozen or so locations where code will need to be added. :line -Fix styles :link(fix),h4 +10.6 Fix styles :link(10_6),h4 In LAMMPS, a "fix" is any operation that is computed during timestepping that alters some property of the system. Essentially @@ -342,7 +340,7 @@ quantities and/or to be summed to the potential energy of the system. :line -Input script commands :link(command),h4 +10.7 Input script commands :link(10_7),h4 New commands can be added to LAMMPS input scripts by adding new classes that have a "command" method. For example, the create_atoms, @@ -362,7 +360,7 @@ needed. :line -Kspace computations :link(kspace),h4 +10.8 Kspace computations :link(10_8),h4 Classes that compute long-range Coulombic interactions via K-space representations (Ewald, PPPM) are derived from the KSpace class. New @@ -380,7 +378,7 @@ memory_usage: tally of memory usage :tb(s=:) :line -Minimization solvers :link(min),h4 +10.9 Minimization styles :link(10_9),h4 Classes that perform energy minimization derived from the Min class. New styles can be created to add new minimization algorithms to @@ -397,7 +395,7 @@ memory_usage: tally of memory usage :tb(s=:) :line -Pairwise potentials :link(pair),h4 +10.10 Pairwise potentials :link(10_10),h4 Classes that compute pairwise interactions are derived from the Pair class. In LAMMPS, pairwise calculation include manybody potentials @@ -424,7 +422,7 @@ The inner/middle/outer routines are optional. :line -Region styles :link(region),h4 +10.11 Region styles :link(10_11),h4 Classes that define geometric regions are derived from the Region class. Regions are used elsewhere in LAMMPS to group atoms, delete @@ -440,7 +438,7 @@ match: determine whether a point is in the region :tb(s=:) :line -Thermodynamic output options :link(thermo),h4 +10.12 Thermodynamic output options :link(10_12),h4 There is one class that computes and prints thermodynamic information to the screen and log file; see the file thermo.cpp. @@ -469,7 +467,7 @@ by adding a new keyword to the thermo command. :line -Variable options :link(variable),h4 +10.13 Variable options :link(10_13),h4 There is one class that computes and stores "variable"_variable.html information in LAMMPS; see the file variable.cpp. The value @@ -507,9 +505,10 @@ Adding new "compute styles"_compute.html (whose calculated values can then be accessed by variables) was discussed "here"_Section_modify.html#compute on this page. +:line :line -Submitting new features to the developers to include in LAMMPS :link(package),h4 +10.14 Submitting new features for inclusion in LAMMPS :link(10_14),h4 We encourage users to submit new features that they add to LAMMPS to "the developers"_http://lammps.sandia.gov/authors.html, especially if diff --git a/doc/Section_perf.html b/doc/Section_perf.html index bf95445aa0..330d99407a 100644 --- a/doc/Section_perf.html +++ b/doc/Section_perf.html @@ -9,7 +9,7 @@


    -

    6. Performance & scalability +

    8. Performance & scalability

    LAMMPS performance on several prototypical benchmarks and machines is discussed on the Benchmarks page of the LAMMPS WWW Site where diff --git a/doc/Section_perf.txt b/doc/Section_perf.txt index 8a20a8209b..896d522cac 100644 --- a/doc/Section_perf.txt +++ b/doc/Section_perf.txt @@ -6,7 +6,7 @@ :line -6. Performance & scalability :h3 +8. Performance & scalability :h3 LAMMPS performance on several prototypical benchmarks and machines is discussed on the Benchmarks page of the "LAMMPS WWW Site"_lws where diff --git a/doc/Section_python.html b/doc/Section_python.html index ca2e40ee98..471fc0b5e1 100644 --- a/doc/Section_python.html +++ b/doc/Section_python.html @@ -1,5 +1,5 @@ -

    Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section +
    Previous Section - LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands - Next Section
    @@ -9,7 +9,7 @@
    -

    9. Python interface to LAMMPS +

    11. Python interface to LAMMPS

    The LAMMPS distribution includes some Python code in its python directory which wraps the library interface to LAMMPS. This makes it @@ -88,13 +88,13 @@ setup discussion. The next to last sub-section describes the Python syntax used to invoke LAMMPS. The last sub-section describes example Python scripts included in the python directory.

    -
    • Extending Python with a serial version of LAMMPS -
    • Creating a shared MPI library -
    • Extending Python with a parallel version of LAMMPS -
    • Extending Python with MPI -
    • Testing the Python-LAMMPS interface -
    • Using LAMMPS from Python -
    • Example Python scripts that use LAMMPS +

      Before proceeding, there are 2 items to note.

      @@ -134,7 +134,7 @@ LAMMPS wrapper.
      -

      Extending Python with a serial version of LAMMPS +

      11.1 Extending Python with a serial version of LAMMPS

      From the python directory in the LAMMPS distribution, type

      @@ -164,7 +164,7 @@ this, where you should replace "foo" with your directory of choice.


      -

      Creating a shared MPI library +

      11.2 Creating a shared MPI library

      A shared library is one that is dynamically loadable, which is what Python requires. On Linux this is a library file that ends in ".so", @@ -195,7 +195,7 @@ stand-alone code.


      -

      Extending Python with a parallel version of LAMMPS +

      11.3 Extending Python with a parallel version of LAMMPS

      From the python directory, type

      @@ -233,7 +233,7 @@ will be put in the appropriate directory.


      -

      Extending Python with MPI +

      11.4 Extending Python with MPI

      There are several Python packages available that purport to wrap MPI as a library and allow MPI functions to be called from Python. @@ -308,7 +308,7 @@ print "Proc %d out of %d procs" % (pypar.rank(),pypar.size())


      -

      Testing the Python-LAMMPS interface +

      11.5 Testing the Python-LAMMPS interface

      Before using LAMMPS in a Python program, one more step is needed. The interface to LAMMPS is via the Python ctypes package, which loads the @@ -402,7 +402,7 @@ Python on a single processor, not in parallel.


      -

      Using LAMMPS from Python +

      11.6 Using LAMMPS from Python

      The Python interface to LAMMPS consists of a Python "lammps" module, the source code for which is in python/lammps.py, which creates a @@ -594,7 +594,7 @@ Python script. Isn't ctypes amazing?


      -

      Example Python scripts that use LAMMPS +

      11.7 Example Python scripts that use LAMMPS

      These are the Python scripts included as demos in the python/examples directory of the LAMMPS distribution, to illustrate the kinds of diff --git a/doc/Section_python.txt b/doc/Section_python.txt index f914f9b451..172a00fdc5 100644 --- a/doc/Section_python.txt +++ b/doc/Section_python.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_modify.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_accelerate.html :c +"Previous Section"_Section_modify.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_errors.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) @@ -6,7 +6,7 @@ :line -9. Python interface to LAMMPS :h3 +11. Python interface to LAMMPS :h3 The LAMMPS distribution includes some Python code in its python directory which wraps the library interface to LAMMPS. This makes it @@ -85,13 +85,13 @@ setup discussion. The next to last sub-section describes the Python syntax used to invoke LAMMPS. The last sub-section describes example Python scripts included in the python directory. -"Extending Python with a serial version of LAMMPS"_#9_1 -"Creating a shared MPI library"_#9_2 -"Extending Python with a parallel version of LAMMPS"_#9_3 -"Extending Python with MPI"_#9_4 -"Testing the Python-LAMMPS interface"_#9_5 -"Using LAMMPS from Python"_#9_6 -"Example Python scripts that use LAMMPS"_#9_7 :ul +11.1 "Extending Python with a serial version of LAMMPS"_#11_1 +11.2 "Creating a shared MPI library"_#11_2 +11.3 "Extending Python with a parallel version of LAMMPS"_#11_3 +11.4 "Extending Python with MPI"_#11_4 +11.5 "Testing the Python-LAMMPS interface"_#11_5 +11.6 "Using LAMMPS from Python"_#11_6 +11.7 "Example Python scripts that use LAMMPS"_#11_7 :ul Before proceeding, there are 2 items to note. @@ -130,7 +130,7 @@ LAMMPS wrapper. :line :line -Extending Python with a serial version of LAMMPS :link(9_1),h4 +11.1 Extending Python with a serial version of LAMMPS :link(11_1),h4 From the python directory in the LAMMPS distribution, type @@ -160,7 +160,7 @@ If these commands are successful, a {lammps.py} and :line -Creating a shared MPI library :link(9_2),h4 +11.2 Creating a shared MPI library :link(11_2),h4 A shared library is one that is dynamically loadable, which is what Python requires. On Linux this is a library file that ends in ".so", @@ -191,7 +191,7 @@ stand-alone code. :line -Extending Python with a parallel version of LAMMPS :link(9_3),h4 +11.3 Extending Python with a parallel version of LAMMPS :link(11_3),h4 From the python directory, type @@ -229,7 +229,7 @@ will be put in the appropriate directory. :line -Extending Python with MPI :link(9_4),h4 +11.4 Extending Python with MPI :link(11_4),h4 There are several Python packages available that purport to wrap MPI as a library and allow MPI functions to be called from Python. @@ -304,7 +304,7 @@ and see one line of output for each processor you ran on. :line -Testing the Python-LAMMPS interface :link(9_5),h4 +11.5 Testing the Python-LAMMPS interface :link(11_5),h4 Before using LAMMPS in a Python program, one more step is needed. The interface to LAMMPS is via the Python ctypes package, which loads the @@ -397,7 +397,7 @@ Python on a single processor, not in parallel. :line :line -Using LAMMPS from Python :link(9_6),h4 +11.6 Using LAMMPS from Python :link(11_6),h4 The Python interface to LAMMPS consists of a Python "lammps" module, the source code for which is in python/lammps.py, which creates a @@ -588,7 +588,7 @@ Python script. Isn't ctypes amazing? :l,ule :line :line -Example Python scripts that use LAMMPS :link(9_7),h4 +11.7 Example Python scripts that use LAMMPS :link(11_7),h4 These are the Python scripts included as demos in the python/examples directory of the LAMMPS distribution, to illustrate the kinds of diff --git a/doc/Section_tools.html b/doc/Section_tools.html index 4e1228a21d..3f9efb0c7e 100644 --- a/doc/Section_tools.html +++ b/doc/Section_tools.html @@ -11,7 +11,7 @@ Section


      -

      7. Additional tools +

      9. Additional tools

      LAMMPS is designed to be a computational kernel for performing molecular dynamics computations. Additional pre- and post-processing diff --git a/doc/Section_tools.txt b/doc/Section_tools.txt index 5c3f7bf6a1..05a4fe65c0 100644 --- a/doc/Section_tools.txt +++ b/doc/Section_tools.txt @@ -8,7 +8,7 @@ Section"_Section_modify.html :c :line -7. Additional tools :h3 +9. Additional tools :h3 LAMMPS is designed to be a computational kernel for performing molecular dynamics computations. Additional pre- and post-processing From a3add0b021f82337388fc80f9995cd3f1dcbc742 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 25 Aug 2011 16:46:23 +0000 Subject: [PATCH 037/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6808 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Manual.html | 144 +++++++-------- doc/Manual.txt | 286 ++++++++++++++--------------- doc/Section_accelerate.html | 30 +-- doc/Section_accelerate.txt | 26 +-- doc/Section_commands.html | 21 ++- doc/Section_commands.txt | 21 ++- doc/Section_errors.html | 2 +- doc/Section_errors.txt | 2 +- doc/Section_howto.html | 39 ++-- doc/Section_howto.txt | 39 ++-- doc/Section_intro.html | 26 +-- doc/Section_intro.txt | 26 +-- doc/Section_modify.html | 14 +- doc/Section_modify.txt | 14 +- doc/Section_python.html | 19 +- doc/Section_python.txt | 19 +- doc/Section_start.html | 105 +++++------ doc/Section_start.txt | 105 +++++------ doc/angle_charmm.html | 2 +- doc/angle_charmm.txt | 2 +- doc/angle_class2.html | 2 +- doc/angle_class2.txt | 2 +- doc/angle_cmm.html | 4 +- doc/angle_cmm.txt | 4 +- doc/angle_cosine.html | 2 +- doc/angle_cosine.txt | 2 +- doc/angle_cosine_delta.html | 2 +- doc/angle_cosine_delta.txt | 2 +- doc/angle_cosine_periodic.html | 2 +- doc/angle_cosine_periodic.txt | 2 +- doc/angle_cosine_shift.html | 4 +- doc/angle_cosine_shift.txt | 4 +- doc/angle_cosine_shift_exp.html | 4 +- doc/angle_cosine_shift_exp.txt | 4 +- doc/angle_cosine_squared.html | 2 +- doc/angle_cosine_squared.txt | 2 +- doc/angle_harmonic.html | 2 +- doc/angle_harmonic.txt | 2 +- doc/angle_hybrid.html | 2 +- doc/angle_hybrid.txt | 2 +- doc/angle_style.html | 6 +- doc/angle_style.txt | 4 +- doc/angle_table.html | 2 +- doc/angle_table.txt | 2 +- doc/atom_style.html | 2 +- doc/atom_style.txt | 2 +- doc/bond_class2.html | 4 +- doc/bond_class2.txt | 4 +- doc/bond_fene.html | 2 +- doc/bond_fene.txt | 2 +- doc/bond_fene_expand.html | 2 +- doc/bond_fene_expand.txt | 2 +- doc/bond_harmonic.html | 2 +- doc/bond_harmonic.txt | 2 +- doc/bond_harmonic_shift.html | 4 +- doc/bond_harmonic_shift.txt | 4 +- doc/bond_harmonic_shift_cut.html | 4 +- doc/bond_harmonic_shift_cut.txt | 4 +- doc/bond_hybrid.html | 2 +- doc/bond_hybrid.txt | 2 +- doc/bond_morse.html | 2 +- doc/bond_morse.txt | 2 +- doc/bond_nonlinear.html | 2 +- doc/bond_nonlinear.txt | 2 +- doc/bond_quartic.html | 2 +- doc/bond_quartic.txt | 2 +- doc/bond_style.html | 6 +- doc/bond_style.txt | 4 +- doc/bond_table.html | 2 +- doc/bond_table.txt | 2 +- doc/compute_ackland_atom.html | 2 +- doc/compute_ackland_atom.txt | 2 +- doc/compute_damage_atom.html | 2 +- doc/compute_damage_atom.txt | 2 +- doc/compute_event_displace.html | 4 +- doc/compute_event_displace.txt | 4 +- doc/compute_ke_atom_eff.html | 2 +- doc/compute_ke_atom_eff.txt | 2 +- doc/compute_ke_eff.html | 2 +- doc/compute_ke_eff.txt | 2 +- doc/compute_pe.html | 8 +- doc/compute_pe.txt | 6 +- doc/compute_pressure.html | 8 +- doc/compute_pressure.txt | 6 +- doc/compute_temp.html | 8 +- doc/compute_temp.txt | 6 +- doc/compute_temp_asphere.html | 2 +- doc/compute_temp_asphere.txt | 2 +- doc/compute_temp_deform_eff.html | 2 +- doc/compute_temp_deform_eff.txt | 2 +- doc/compute_temp_eff.html | 2 +- doc/compute_temp_eff.txt | 2 +- doc/compute_temp_partial.html | 8 +- doc/compute_temp_partial.txt | 6 +- doc/compute_temp_region_eff.html | 2 +- doc/compute_temp_region_eff.txt | 2 +- doc/compute_temp_rotate.html | 2 +- doc/compute_temp_rotate.txt | 2 +- doc/dihedral_charmm.html | 2 +- doc/dihedral_charmm.txt | 2 +- doc/dihedral_class2.html | 2 +- doc/dihedral_class2.txt | 2 +- doc/dihedral_cosine_shift_exp.html | 4 +- doc/dihedral_cosine_shift_exp.txt | 4 +- doc/dihedral_harmonic.html | 2 +- doc/dihedral_harmonic.txt | 2 +- doc/dihedral_helix.html | 2 +- doc/dihedral_helix.txt | 2 +- doc/dihedral_hybrid.html | 2 +- doc/dihedral_hybrid.txt | 2 +- doc/dihedral_multi_harmonic.html | 2 +- doc/dihedral_multi_harmonic.txt | 2 +- doc/dihedral_opls.html | 2 +- doc/dihedral_opls.txt | 2 +- doc/dihedral_style.html | 8 +- doc/dihedral_style.txt | 6 +- doc/dump.html | 33 ++-- doc/dump.txt | 31 ++-- doc/dump_image.html | 8 +- doc/dump_image.txt | 6 +- doc/echo.html | 4 +- doc/echo.txt | 4 +- doc/fix.html | 6 +- doc/fix.txt | 4 +- doc/fix_addforce.html | 8 +- doc/fix_addforce.txt | 6 +- doc/fix_addtorque.html | 2 +- doc/fix_addtorque.txt | 2 +- doc/fix_atc.html | 2 +- doc/fix_atc.txt | 2 +- doc/fix_aveforce.html | 8 +- doc/fix_aveforce.txt | 6 +- doc/fix_bond_break.html | 2 +- doc/fix_bond_break.txt | 2 +- doc/fix_bond_create.html | 2 +- doc/fix_bond_create.txt | 2 +- doc/fix_bond_swap.html | 2 +- doc/fix_bond_swap.txt | 2 +- doc/fix_enforce2d.html | 8 +- doc/fix_enforce2d.txt | 6 +- doc/fix_freeze.html | 10 +- doc/fix_freeze.txt | 8 +- doc/fix_gcmc.html | 2 +- doc/fix_gcmc.txt | 2 +- doc/fix_gravity.html | 8 +- doc/fix_gravity.txt | 6 +- doc/fix_imd.html | 2 +- doc/fix_imd.txt | 2 +- doc/fix_langevin_eff.html | 2 +- doc/fix_langevin_eff.txt | 2 +- doc/fix_msst.html | 2 +- doc/fix_msst.txt | 2 +- doc/fix_neb.html | 4 +- doc/fix_neb.txt | 4 +- doc/fix_nh.html | 8 +- doc/fix_nh.txt | 6 +- doc/fix_nh_eff.html | 2 +- doc/fix_nh_eff.txt | 2 +- doc/fix_nph_asphere.html | 2 +- doc/fix_nph_asphere.txt | 2 +- doc/fix_npt_asphere.html | 2 +- doc/fix_npt_asphere.txt | 2 +- doc/fix_nve.html | 8 +- doc/fix_nve.txt | 6 +- doc/fix_nve_asphere.html | 2 +- doc/fix_nve_asphere.txt | 2 +- doc/fix_nve_eff.html | 2 +- doc/fix_nve_eff.txt | 2 +- doc/fix_nvt_asphere.html | 2 +- doc/fix_nvt_asphere.txt | 2 +- doc/fix_nvt_sllod_eff.html | 2 +- doc/fix_nvt_sllod_eff.txt | 2 +- doc/fix_poems.html | 2 +- doc/fix_poems.txt | 2 +- doc/fix_pour.html | 2 +- doc/fix_pour.txt | 2 +- doc/fix_qeq_reax.html | 2 +- doc/fix_qeq_reax.txt | 2 +- doc/fix_reax_bonds.html | 2 +- doc/fix_reax_bonds.txt | 2 +- doc/fix_setforce.html | 8 +- doc/fix_setforce.txt | 6 +- doc/fix_shake.html | 8 +- doc/fix_shake.txt | 6 +- doc/fix_smd.html | 2 +- doc/fix_smd.txt | 2 +- doc/fix_srd.html | 4 +- doc/fix_srd.txt | 4 +- doc/fix_temp_berendsen.html | 8 +- doc/fix_temp_berendsen.txt | 6 +- doc/fix_temp_rescale.html | 8 +- doc/fix_temp_rescale.txt | 6 +- doc/fix_temp_rescale_eff.html | 2 +- doc/fix_temp_rescale_eff.txt | 2 +- doc/fix_tmd.html | 4 +- doc/fix_tmd.txt | 4 +- doc/fix_viscous.html | 8 +- doc/fix_viscous.txt | 6 +- doc/fix_wall_gran.html | 2 +- doc/fix_wall_gran.txt | 2 +- doc/improper_class2.html | 2 +- doc/improper_class2.txt | 2 +- doc/improper_cvff.html | 2 +- doc/improper_cvff.txt | 2 +- doc/improper_harmonic.html | 2 +- doc/improper_harmonic.txt | 2 +- doc/improper_hybrid.html | 2 +- doc/improper_hybrid.txt | 2 +- doc/improper_style.html | 8 +- doc/improper_style.txt | 6 +- doc/improper_umbrella.html | 2 +- doc/improper_umbrella.txt | 2 +- doc/jump.html | 9 +- doc/jump.txt | 9 +- doc/kspace_style.html | 8 +- doc/kspace_style.txt | 8 +- doc/log.html | 3 +- doc/log.txt | 3 +- doc/neb.html | 16 +- doc/neb.txt | 16 +- doc/neighbor.html | 2 +- doc/neighbor.txt | 2 +- doc/next.html | 2 +- doc/next.txt | 2 +- doc/package.html | 8 +- doc/package.txt | 8 +- doc/pair_airebo.html | 4 +- doc/pair_airebo.txt | 4 +- doc/pair_born.html | 12 +- doc/pair_born.txt | 10 +- doc/pair_buck.html | 12 +- doc/pair_buck.txt | 10 +- doc/pair_buck_coul.html | 2 +- doc/pair_buck_coul.txt | 2 +- doc/pair_charmm.html | 14 +- doc/pair_charmm.txt | 10 +- doc/pair_class2.html | 10 +- doc/pair_class2.txt | 8 +- doc/pair_cmm.html | 10 +- doc/pair_cmm.txt | 8 +- doc/pair_colloid.html | 2 +- doc/pair_colloid.txt | 2 +- doc/pair_comb.html | 2 +- doc/pair_comb.txt | 2 +- doc/pair_coul.html | 12 +- doc/pair_coul.txt | 10 +- doc/pair_dipole.html | 4 +- doc/pair_dipole.txt | 4 +- doc/pair_dsmc.html | 4 +- doc/pair_dsmc.txt | 6 +- doc/pair_eam.html | 12 +- doc/pair_eam.txt | 10 +- doc/pair_eff.html | 4 +- doc/pair_eff.txt | 4 +- doc/pair_gayberne.html | 10 +- doc/pair_gayberne.txt | 8 +- doc/pair_gran.html | 10 +- doc/pair_gran.txt | 8 +- doc/pair_gromacs.html | 8 +- doc/pair_gromacs.txt | 6 +- doc/pair_lj.html | 10 +- doc/pair_lj.txt | 8 +- doc/pair_lj96.html | 8 +- doc/pair_lj96.txt | 6 +- doc/pair_lj_coul.html | 2 +- doc/pair_lj_coul.txt | 2 +- doc/pair_lj_expand.html | 8 +- doc/pair_lj_expand.txt | 6 +- doc/pair_lj_sf.html | 2 +- doc/pair_lj_sf.txt | 2 +- doc/pair_lj_smooth.html | 8 +- doc/pair_lj_smooth.txt | 6 +- doc/pair_lubricate.html | 2 +- doc/pair_lubricate.txt | 2 +- doc/pair_meam.html | 2 +- doc/pair_meam.txt | 2 +- doc/pair_morse.html | 8 +- doc/pair_morse.txt | 6 +- doc/pair_peri.html | 3 +- doc/pair_peri.txt | 3 +- doc/pair_reax_c.html | 2 +- doc/pair_reax_c.txt | 2 +- doc/pair_resquared.html | 10 +- doc/pair_resquared.txt | 8 +- doc/pair_style.html | 6 +- doc/pair_style.txt | 4 +- doc/pair_sw.html | 2 +- doc/pair_sw.txt | 2 +- doc/pair_tersoff.html | 2 +- doc/pair_tersoff.txt | 2 +- doc/pair_tersoff_zbl.html | 2 +- doc/pair_tersoff_zbl.txt | 2 +- doc/pair_yukawa_colloid.html | 2 +- doc/pair_yukawa_colloid.txt | 2 +- doc/prd.html | 19 +- doc/prd.txt | 19 +- doc/processors.html | 6 +- doc/processors.txt | 4 +- doc/read_data.html | 4 +- doc/read_data.txt | 4 +- doc/suffix.html | 10 +- doc/suffix.txt | 8 +- doc/tad.html | 4 +- doc/tad.txt | 4 +- doc/temper.html | 18 +- doc/temper.txt | 18 +- doc/variable.html | 12 +- doc/variable.txt | 12 +- 308 files changed, 1151 insertions(+), 1121 deletions(-) diff --git a/doc/Manual.html b/doc/Manual.html index 27fd5eb36f..bcb1500514 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -82,107 +82,107 @@ it gives quick access to documentation for all LAMMPS commands.

      1. Introduction -
      diff --git a/doc/Manual.txt b/doc/Manual.txt index 1a8107aee2..2b645ae715 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -77,172 +77,172 @@ it gives quick access to documentation for all LAMMPS commands. "htmldoc"_http://www.easysw.com/htmldoc "Introduction"_Section_intro.html :olb,l - 1.1 "What is LAMMPS"_1_1 :ulb,b - 1.2 "LAMMPS features"_1_2 :b - 1.3 "LAMMPS non-features"_1_3 :b - 1.4 "Open source distribution"_1_4 :b - 1.5 "Acknowledgments and citations"_1_5 :ule,b + 1.1 "What is LAMMPS"_intro_1 :ulb,b + 1.2 "LAMMPS features"_intro_2 :b + 1.3 "LAMMPS non-features"_intro_3 :b + 1.4 "Open source distribution"_intro_4 :b + 1.5 "Acknowledgments and citations"_intro_5 :ule,b "Getting started"_Section_start.html :l - 2.1 "What's in the LAMMPS distribution"_2_1 :ulb,b - 2.2 "Making LAMMPS"_2_2 :b - 2.3 "Making LAMMPS with optional packages"_2_3 :b - 2.4 "Building LAMMPS as a library"_2_4 :b - 2.5 "Running LAMMPS"_2_5 :b - 2.6 "Command-line options"_2_6 :b - 2.7 "Screen output"_2_7 :b + 2.1 "What's in the LAMMPS distribution"_start_1 :ulb,b + 2.2 "Making LAMMPS"_start_2 :b + 2.3 "Making LAMMPS with optional packages"_start_3 :b + 2.4 "Building LAMMPS as a library"_start_4 :b + 2.5 "Running LAMMPS"_start_5 :b + 2.6 "Command-line options"_start_6 :b + 2.7 "Screen output"_start_7 :b 2.8 "Tips for users of previous versions"_2_8 :ule,b "Commands"_Section_commands.html :l - 3.1 "LAMMPS input script"_3_1 :ulb,b - 3.2 "Parsing rules"_3_2 :b - 3.3 "Input script structure"_3_3 :b - 3.4 "Commands listed by category"_3_4 :b - 3.5 "Commands listed alphabetically"_3_5 :ule,b + 3.1 "LAMMPS input script"_cmd_1 :ulb,b + 3.2 "Parsing rules"_cmd_2 :b + 3.3 "Input script structure"_cmd_3 :b + 3.4 "Commands listed by category"_cmd_4 :b + 3.5 "Commands listed alphabetically"_cmd_5 :ule,b "Packages"_Section_packages.html :l - 4.1 "Standard packages"_3_1 :ulb,b - 4.2 "User packages"_3_2 :ule,b + 4.1 "Standard packages"_pkg_1 :ulb,b + 4.2 "User packages"_pkg_2 :ule,b "Using accelerated CPU and GPU styles"_Section_accelerate.html :l - 5.1 "OPT package"_10_1 :ulb,b - 5.2 "USER-OMP package"_10_2 :b - 5.3 "GPU package"_10_3 :b - 5.4 "USER-CUDA package"_10_4 :b - 5.5 "Comparison of GPU and USER-CUDA packages"_10_5 :ule,b + 5.1 "OPT package"_acc_1 :ulb,b + 5.2 "USER-OMP package"_acc_2 :b + 5.3 "GPU package"_acc_3 :b + 5.4 "USER-CUDA package"_acc_4 :b + 5.5 "Comparison of GPU and USER-CUDA packages"_acc_5 :ule,b "How-to discussions"_Section_howto.html :l - 6.1 "Restarting a simulation"_4_1 :ulb,b - 6.2 "2d simulations"_4_2 :b - 6.3 "CHARMM and AMBER force fields"_4_3 :b - 6.4 "Running multiple simulations from one input script"_4_4 :b - 6.5 "Multi-replica simulations"_4_5 :b - 6.6 "Granular models"_4_6 :b - 6.7 "TIP3P water model"_4_7 :b - 6.8 "TIP4P water model"_4_8 :b - 6.9 "SPC water model"_4_9 :b - 6.10 "Coupling LAMMPS to other codes"_4_10 :b - 6.11 "Visualizing LAMMPS snapshots"_4_11 :b - 6.12 "Triclinic (non-orthogonal) simulation boxes"_4_12 :b - 6.13 "NEMD simulations"_4_13 :b - 6.14 "Extended spherical and aspherical particles"_4_14 :b - 6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_4_15 :b - 6.16 "Thermostatting, barostatting, and compute temperature"_4_16 :b - 6.17 "Walls"_4_17 :b - 6.18 "Elastic constants"_4_18 :b - 6.19 "Library interface to LAMMPS"_4_19 :b - 6.20 "Calculating thermal conductivity"_4_20 :b - 6.21 "Calculating viscosity"_4_21 :ule,b + 6.1 "Restarting a simulation"_howto_1 :ulb,b + 6.2 "2d simulations"_howto_2 :b + 6.3 "CHARMM and AMBER force fields"_howto_3 :b + 6.4 "Running multiple simulations from one input script"_howto_4 :b + 6.5 "Multi-replica simulations"_howto_5 :b + 6.6 "Granular models"_howto_6 :b + 6.7 "TIP3P water model"_howto_7 :b + 6.8 "TIP4P water model"_howto_8 :b + 6.9 "SPC water model"_howto_9 :b + 6.10 "Coupling LAMMPS to other codes"_howto_10 :b + 6.11 "Visualizing LAMMPS snapshots"_howto_11 :b + 6.12 "Triclinic (non-orthogonal) simulation boxes"_howto_12 :b + 6.13 "NEMD simulations"_howto_13 :b + 6.14 "Extended spherical and aspherical particles"_howto_14 :b + 6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_howto_15 :b + 6.16 "Thermostatting, barostatting, and compute temperature"_howto_16 :b + 6.17 "Walls"_howto_17 :b + 6.18 "Elastic constants"_howto_18 :b + 6.19 "Library interface to LAMMPS"_howto_19 :b + 6.20 "Calculating thermal conductivity"_howto_20 :b + 6.21 "Calculating viscosity"_howto_21 :ule,b "Example problems"_Section_example.html :l "Performance & scalability"_Section_perf.html :l "Additional tools"_Section_tools.html :l "Modifying & extending LAMMPS"_Section_modify.html :l - 10.1 "Atom styles"_10_1 :ulb,b - 10.2 "Bond, angle, dihedral, improper potentials"_10_2 :b - 10.3 "Compute styles"_10_3 :b - 10.4 "Dump styles"_10_4 :b - 10.5 "Dump custom output options"_10_5 :b - 10.6 "Fix styles"_10_6 :b - 10.7 "Input script commands"_10_7 :b - 10.8 "Kspace computations"_10_8 :b - 10.9 "Minimization styles"_10_9 :b - 10.10 "Pairwise potentials"_10_10 :b - 10.11 "Region styles"_10_11 :b - 10.12 "Thermodynamic output options"_10_12 :b - 10.13 "Variable options"_10_13 :b - 10.14 "Submitting new features for inclusion in LAMMPS"_10_14 :ule,b + 10.1 "Atom styles"_mod_1 :ulb,b + 10.2 "Bond, angle, dihedral, improper potentials"_mod_2 :b + 10.3 "Compute styles"_mod_3 :b + 10.4 "Dump styles"_mod_4 :b + 10.5 "Dump custom output options"_mod_5 :b + 10.6 "Fix styles"_mod_6 :b + 10.7 "Input script commands"_mod_7 :b + 10.8 "Kspace computations"_mod_8 :b + 10.9 "Minimization styles"_mod_9 :b + 10.10 "Pairwise potentials"_mod_10 :b + 10.11 "Region styles"_mod_11 :b + 10.12 "Thermodynamic output options"_mod_12 :b + 10.13 "Variable options"_mod_13 :b + 10.14 "Submitting new features for inclusion in LAMMPS"_mod_14 :ule,b "Python interface"_Section_python.html :l - 11.1 "Extending Python with a serial version of LAMMPS"_9_1 :ulb,b - 11.2 "Creating a shared MPI library"_9_2 :b - 11.3 "Extending Python with a parallel version of LAMMPS"_9_3 :b - 11.4 "Extending Python with MPI"_9_4 :b - 11.5 "Testing the Python-LAMMPS interface"_9_5 :b - 11.6 "Using LAMMPS from Python"_9_6 :b - 11.7 "Example Python scripts that use LAMMPS"_9_7 :ule,b + 11.1 "Extending Python with a serial version of LAMMPS"_py_1 :ulb,b + 11.2 "Creating a shared MPI library"_py_2 :b + 11.3 "Extending Python with a parallel version of LAMMPS"_py_3 :b + 11.4 "Extending Python with MPI"_py_4 :b + 11.5 "Testing the Python-LAMMPS interface"_py_5 :b + 11.6 "Using LAMMPS from Python"_py_6 :b + 11.7 "Example Python scripts that use LAMMPS"_py_7 :ule,b "Errors"_Section_errors.html :l - 12.1 "Common problems"_11_1 :ulb,b - 12.2 "Reporting bugs"_11_2 :b - 12.3 "Error & warning messages"_11_3 :ule,b + 12.1 "Common problems"_err_1 :ulb,b + 12.2 "Reporting bugs"_err_2 :b + 12.3 "Error & warning messages"_err_3 :ule,b "Future and history"_Section_history.html :l - 13.1 "Coming attractions"_12_1 :ulb,b - 13.2 "Past versions"_12_2 :ule,b + 13.1 "Coming attractions"_hist_1 :ulb,b + 13.2 "Past versions"_hist_2 :ule,b :ole -:link(1_1,Section_intro.html#1_1) -:link(1_2,Section_intro.html#1_2) -:link(1_3,Section_intro.html#1_3) -:link(1_4,Section_intro.html#1_4) -:link(1_5,Section_intro.html#1_5) +:link(intro_1,Section_intro.html#intro_1) +:link(intro_2,Section_intro.html#intro_2) +:link(intro_3,Section_intro.html#intro_3) +:link(intro_4,Section_intro.html#intro_4) +:link(intro_5,Section_intro.html#intro_5) -:link(2_1,Section_start.html#2_1) -:link(2_2,Section_start.html#2_2) -:link(2_3,Section_start.html#2_3) -:link(2_4,Section_start.html#2_4) -:link(2_5,Section_start.html#2_5) -:link(2_6,Section_start.html#2_6) -:link(2_7,Section_start.html#2_7) -:link(2_8,Section_start.html#2_8) +:link(start_1,Section_start.html#start_1) +:link(start_2,Section_start.html#start_2) +:link(start_3,Section_start.html#start_3) +:link(start_4,Section_start.html#start_4) +:link(start_5,Section_start.html#start_5) +:link(start_6,Section_start.html#start_6) +:link(start_7,Section_start.html#start_7) +:link(start_8,Section_start.html#start_8) -:link(3_1,Section_commands.html#3_1) -:link(3_2,Section_commands.html#3_2) -:link(3_3,Section_commands.html#3_3) -:link(3_4,Section_commands.html#3_4) -:link(3_5,Section_commands.html#3_5) +:link(cmd_1,Section_commands.html#cmd_1) +:link(cmd_2,Section_commands.html#cmd_2) +:link(cmd_3,Section_commands.html#cmd_3) +:link(cmd_4,Section_commands.html#cmd_4) +:link(cmd_5,Section_commands.html#cmd_5) -:link(4_1,Section_commands.html#4_1) -:link(4_2,Section_commands.html#4_2) +:link(pkg_1,Section_packages.html#pkg_1) +:link(pkg_2,Section_packages.html#pkg_2) -:link(5_1,Section_commands.html#4_1) -:link(5_2,Section_commands.html#4_2) -:link(5_3,Section_commands.html#4_2) -:link(5_4,Section_commands.html#4_2) -:link(5_5,Section_commands.html#4_2) +:link(acc_1,Section_accelerate.html#acc_1) +:link(acc_2,Section_accelerate.html#acc_2) +:link(acc_3,Section_accelerate.html#acc_3) +:link(acc_4,Section_accelerate.html#acc_4) +:link(acc_5,Section_accelerate.html#acc_5) -:link(6_1,Section_howto.html#4_1) -:link(6_2,Section_howto.html#4_2) -:link(6_3,Section_howto.html#4_3) -:link(6_4,Section_howto.html#4_4) -:link(6_5,Section_howto.html#4_5) -:link(6_6,Section_howto.html#4_6) -:link(6_7,Section_howto.html#4_7) -:link(6_8,Section_howto.html#4_8) -:link(6_9,Section_howto.html#4_9) -:link(6_10,Section_howto.html#6_10) -:link(6_11,Section_howto.html#6_11) -:link(6_12,Section_howto.html#4_12) -:link(6_13,Section_howto.html#4_13) -:link(6_14,Section_howto.html#4_14) -:link(6_15,Section_howto.html#4_15) -:link(6_16,Section_howto.html#4_16) -:link(6_17,Section_howto.html#4_17) -:link(6_18,Section_howto.html#4_18) -:link(6_19,Section_howto.html#4_19) -:link(6_20,Section_howto.html#4_20) -:link(6_21,Section_howto.html#4_21) +:link(howto_1,Section_howto.html#howto_1) +:link(howto_2,Section_howto.html#howto_2) +:link(howto_3,Section_howto.html#howto_3) +:link(howto_4,Section_howto.html#howto_4) +:link(howto_5,Section_howto.html#howto_5) +:link(howto_6,Section_howto.html#howto_6) +:link(howto_7,Section_howto.html#howto_7) +:link(howto_8,Section_howto.html#howto_8) +:link(howto_9,Section_howto.html#howto_9) +:link(howto_10,Section_howto.html#howto_10) +:link(howto_11,Section_howto.html#howto_11) +:link(howto_12,Section_howto.html#howto_12) +:link(howto_13,Section_howto.html#howto_13) +:link(howto_14,Section_howto.html#howto_14) +:link(howto_15,Section_howto.html#howto_15) +:link(howto_16,Section_howto.html#howto_16) +:link(howto_17,Section_howto.html#howto_17) +:link(howto_18,Section_howto.html#howto_18) +:link(howto_19,Section_howto.html#howto_19) +:link(howto_20,Section_howto.html#howto_20) +:link(howto_21,Section_howto.html#howto_21) -:link(10_1,Section_howto.html#4_1) -:link(10_2,Section_howto.html#4_2) -:link(10_3,Section_howto.html#4_3) -:link(10_4,Section_howto.html#4_4) -:link(10_5,Section_howto.html#4_5) -:link(10_6,Section_howto.html#4_6) -:link(10_7,Section_howto.html#4_7) -:link(10_8,Section_howto.html#4_8) -:link(10_9,Section_howto.html#4_9) -:link(10_10,Section_howto.html#10_10) -:link(10_11,Section_howto.html#10_11) -:link(10_12,Section_howto.html#4_12) -:link(10_13,Section_howto.html#4_13) -:link(10_14,Section_howto.html#4_14) +:link(mod_1,Section_modify.html#mod_1) +:link(mod_2,Section_modify.html#mod_2) +:link(mod_3,Section_modify.html#mod_3) +:link(mod_4,Section_modify.html#mod_4) +:link(mod_5,Section_modify.html#mod_5) +:link(mod_6,Section_modify.html#mod_6) +:link(mod_7,Section_modify.html#mod_7) +:link(mod_8,Section_modify.html#mod_8) +:link(mod_9,Section_modify.html#mod_9) +:link(mod_10,Section_modify.html#mod_10) +:link(mod_11,Section_modify.html#mod_11) +:link(mod_12,Section_modify.html#mod_12) +:link(mod_13,Section_modify.html#mod_13) +:link(mod_14,Section_modify.html#mod_14) -:link(11_1,Section_python.html#9_1) -:link(11_2,Section_python.html#9_2) -:link(11_3,Section_python.html#9_3) -:link(11_4,Section_python.html#9_4) -:link(11_5,Section_python.html#9_5) -:link(11_6,Section_python.html#9_6) -:link(11_7,Section_python.html#9_7) +:link(py_1,Section_python.html#py_1) +:link(py_2,Section_python.html#py_2) +:link(py_3,Section_python.html#py_3) +:link(py_4,Section_python.html#py_4) +:link(py_5,Section_python.html#py_5) +:link(py_6,Section_python.html#py_6) +:link(py_7,Section_python.html#py_7) -:link(12_1,Section_errors.html#11_1) -:link(12_2,Section_errors.html#11_2) -:link(12_3,Section_errors.html#11_3) +:link(err_1,Section_errors.html#err_1) +:link(err_2,Section_errors.html#err_2) +:link(err_3,Section_errors.html#err_3) -:link(13_1,Section_history.html#12_1) -:link(13_2,Section_history.html#12_2) +:link(hist_1,Section_history.html#hist_1) +:link(hist_2,Section_history.html#hist_2) diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html index 4e279faf23..c314ea830b 100644 --- a/doc/Section_accelerate.html +++ b/doc/Section_accelerate.html @@ -36,7 +36,7 @@ style exist in LAMMPS:

    Assuming you have built LAMMPS with the appropriate package, these styles can be invoked by specifying them explicitly in your input -script. Or you can use the -suffix command-line +script. Or you can use the -suffix command-line switch to invoke the accelerated versions automatically, without changing your input script. The suffix command allows you to set a suffix explicitly and @@ -164,10 +164,10 @@ hardware and install specific NVIDIA CUDA software on your system:

    As with other packages that include a separately compiled library, you need to first build the GPU library, before building LAMMPS itself. -General instructions for doing this are in this -section of the manual. For this package, -do the following, using a Makefile in lib/gpu appropriate for your -system: +General instructions for doing this are in this +section of the manual. For this +package, do the following, using a Makefile in lib/gpu appropriate for +your system:

    cd lammps/lib/gpu
     make -f Makefile.linux
    @@ -201,7 +201,7 @@ and in many cases it will be more efficient to run this way.
     

    Description:

    -

    Perform time integration to update internal energy and local density, but not -position or velocity for atoms in the group each timestep. This fix is needed -for SPH simulations to correctly time-integrate fixed boundary particles which -constrain a fluid to a given region in space. +

    Perform time integration to update internal energy and local density, +but not position or velocity for atoms in the group each timestep. +This fix is needed for SPH simulations to correctly time-integrate +fixed boundary particles which constrain a fluid to a given region in +space. +

    +

    See this PDF guide to using SPH in +LAMMPS.

    Restart, fix_modify, output, run start/stop, minimize info:

    @@ -39,7 +43,11 @@ commands. No parameter of this fix can be used with the start/stop keywords of the run command. This fix is not invoked during energy minimization.

    -

    Restrictions: none +

    Restrictions: +

    +

    This fix is part of the USER-SPH package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    diff --git a/doc/fix_meso_stationary.txt b/doc/fix_meso_stationary.txt index be3152dc14..31bdb4b1f3 100644 --- a/doc/fix_meso_stationary.txt +++ b/doc/fix_meso_stationary.txt @@ -21,10 +21,14 @@ fix 1 boundary meso/stationary :pre [Description:] -Perform time integration to update internal energy and local density, but not -position or velocity for atoms in the group each timestep. This fix is needed -for SPH simulations to correctly time-integrate fixed boundary particles which -constrain a fluid to a given region in space. +Perform time integration to update internal energy and local density, +but not position or velocity for atoms in the group each timestep. +This fix is needed for SPH simulations to correctly time-integrate +fixed boundary particles which constrain a fluid to a given region in +space. + +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. [Restart, fix_modify, output, run start/stop, minimize info:] @@ -36,7 +40,11 @@ commands"_Section_howto.html#4_15. No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. This fix is not invoked during "energy minimization"_minimize.html. -[Restrictions:] none +[Restrictions:] + +This fix is part of the USER-SPH package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] diff --git a/doc/pair_meam.html b/doc/pair_meam.html index f0dd319464..8d5868201c 100644 --- a/doc/pair_meam.html +++ b/doc/pair_meam.html @@ -373,7 +373,7 @@ This report may be accessed on-line via -

    (ZBL) J.F. Ziegler, J.P. Biersack, U. Littmark, 'Stopping and Ranges -of Ions in Matter' Vol 1, 1985, Pergamon Press. +

    (ZBL) J.F. Ziegler, J.P. Biersack, U. Littmark, "Stopping and Ranges +of Ions in Matter", Vol 1, 1985, Pergamon Press.

    diff --git a/doc/pair_meam.txt b/doc/pair_meam.txt index ed2ad404d4..b787345ae5 100644 --- a/doc/pair_meam.txt +++ b/doc/pair_meam.txt @@ -363,6 +363,5 @@ This report may be accessed on-line via "this link"_sandreport. [(Wang)] Wang, Van Hove, Ross, Baskes, J. Chem. Phys., 121, 5410 (2004). :link(ZBL) -[(ZBL)] J.F. Ziegler, J.P. Biersack, U. Littmark, 'Stopping and Ranges -of Ions in Matter' Vol 1, 1985, Pergamon Press. - +[(ZBL)] J.F. Ziegler, J.P. Biersack, U. Littmark, "Stopping and Ranges +of Ions in Matter", Vol 1, 1985, Pergamon Press. diff --git a/doc/pair_sph_heatconduction.html b/doc/pair_sph_heatconduction.html index 1c45874a89..570a324b87 100644 --- a/doc/pair_sph_heatconduction.html +++ b/doc/pair_sph_heatconduction.html @@ -17,42 +17,47 @@

    Examples:

    -

    pair_style sph/heatconduction -pair_coeff * * 1.0 2.4 -

    +
    pair_style sph/heatconduction
    +pair_coeff * * 1.0 2.4 
    +

    Description:

    The sph/heatconduction style computes heat transport between SPH particles. The transport model is the diffusion euqation for the internal energy.

    +

    See this PDF guide to using SPH in +LAMMPS. +

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    D diffusion coefficient (length^2/time units) -h kernel function cutoff (distance units) -

    +
    • D diffusion coefficient (length^2/time units) +
    • h kernel function cutoff (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all +

    This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly.

    -

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +

    This style does not support the pair_modify +shift, table, and tail options.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style does not write information to binary restart +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. +

    +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions:

    -

    The pair sph/heatconduction style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    diff --git a/doc/pair_sph_heatconduction.txt b/doc/pair_sph_heatconduction.txt index 3f2c2a93dd..d25debe91b 100644 --- a/doc/pair_sph_heatconduction.txt +++ b/doc/pair_sph_heatconduction.txt @@ -15,45 +15,49 @@ pair_style sph/heatconduction :pre [Examples:] pair_style sph/heatconduction -pair_coeff * * 1.0 2.4 +pair_coeff * * 1.0 2.4 :pre [Description:] The sph/heatconduction style computes heat transport between SPH particles. The transport model is the diffusion euqation for the internal energy. +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. + The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. D diffusion coefficient (length^2/time units) -h kernel function cutoff (distance units) +h kernel function cutoff (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all +This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. -This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style does not write information to "binary restart +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. + +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The {pair sph/heatconduction} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] "pair_coeff"_pair_coeff.html, pair_sph/rhosum [Default:] none - diff --git a/doc/pair_sph_idealgas.html b/doc/pair_sph_idealgas.html index 2c8b917b63..8d5ac22a2d 100644 --- a/doc/pair_sph_idealgas.html +++ b/doc/pair_sph_idealgas.html @@ -17,45 +17,56 @@

    Examples:

    -

    pair_style sph/idealgas -pair_coeff * * 1.0 2.4 -

    +
    pair_style sph/idealgas
    +pair_coeff * * 1.0 2.4 
    +

    Description:

    -

    The sph/idealgas style computes pressure forces between particles according to the ideal gas equation of state, -\beginequation +

    The sph/idealgas style computes pressure forces between particles +according to the ideal gas equation of state: +

    +

    \beginequation p = (\gamma - 1) \rho e, \endequation -where $\gamma=1.4$ is the heat capacity ratio, $\rho$ is the local density, and $e$ is the internal energy per unit mass. This pair style also computes Monaghan's artificial viscosity to prevent particles from interpentrating (Monaghan1983). +

    +

    where gamma = 1.4 is the heat capacity ratio, rho is the local +density, and e is the internal energy per unit mass. This pair style +also computes Monaghan's artificial viscosity to prevent particles +from interpentrating (Monaghan). +

    +

    See this PDF guide to using SPH in +LAMMPS.

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    nu artificial viscosity (no units) -h kernel function cutoff (distance units) -

    +
    • nu artificial viscosity (no units) +
    • h kernel function cutoff (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all +

    This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly.

    -

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +

    This style does not support the pair_modify +shift, table, and tail options.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style does not write information to binary restart +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. +

    +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions:

    -

    The pair sph/idealgas style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    @@ -63,6 +74,11 @@ more info.

    Default: none

    -

    (Monaghan1983) J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. +


    + + + +

    (Monaghan) Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983).

    diff --git a/doc/pair_sph_idealgas.txt b/doc/pair_sph_idealgas.txt index 309b8f8a1a..ad8ef6a0c8 100644 --- a/doc/pair_sph_idealgas.txt +++ b/doc/pair_sph_idealgas.txt @@ -15,45 +15,55 @@ pair_style sph/idealgas :pre [Examples:] pair_style sph/idealgas -pair_coeff * * 1.0 2.4 +pair_coeff * * 1.0 2.4 :pre [Description:] -The sph/idealgas style computes pressure forces between particles according to the ideal gas equation of state, +The sph/idealgas style computes pressure forces between particles +according to the ideal gas equation of state: + \begin{equation} p = (\gamma - 1) \rho e, \end{equation} -where $\gamma=1.4$ is the heat capacity ratio, $\rho$ is the local density, and $e$ is the internal energy per unit mass. This pair style also computes Monaghan's artificial viscosity to prevent particles from interpentrating (Monaghan1983). +where gamma = 1.4 is the heat capacity ratio, rho is the local +density, and e is the internal energy per unit mass. This pair style +also computes Monaghan's artificial viscosity to prevent particles +from interpentrating "(Monaghan)"_#Monoghan. + +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. nu artificial viscosity (no units) -h kernel function cutoff (distance units) +h kernel function cutoff (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all +This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. -This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style does not write information to "binary restart +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. + +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The {pair sph/idealgas} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] @@ -61,5 +71,9 @@ more info. [Default:] none -[(Monaghan1983)] J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. +:line + +:link(Monoghan) +[(Monaghan)] Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983). diff --git a/doc/pair_sph_lj.html b/doc/pair_sph_lj.html index 836cdaefce..60cbdc67c8 100644 --- a/doc/pair_sph_lj.html +++ b/doc/pair_sph_lj.html @@ -17,46 +17,54 @@

    Examples:

    -

    pair_style sph/lj -pair_coeff * * 1.0 2.4 -

    +
    pair_style sph/lj
    +pair_coeff * * 1.0 2.4 
    +

    Description:

    -

    The sph/lj style computes pressure forces between particles according to -the Lennard-Jones equation of state, which is computed according to -Ree's 1980 polynomial fit (Ree1980). The Lennard-Jones parameters -$\epsilon$ and $\sigma$ are set to unity. This pair style also computes +

    The sph/lj style computes pressure forces between particles according +to the Lennard-Jones equation of state, which is computed according to +Ree's 1980 polynomial fit (Ree). The Lennard-Jones parameters +epsilon and sigma are set to unity. This pair style also computes Monaghan's artificial viscosity to prevent particles from -interpentrating (Monaghan1983). +interpentrating (Monaghan). +

    +

    See this PDF guide to using SPH in +LAMMPS.

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    nu artificial viscosity (no units) -h kernel function cutoff (distance units) -

    +
    • nu artificial viscosity (no units) +
    • h kernel function cutoff (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all +

    This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly.

    -

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +

    This style does not support the pair_modify +shift, table, and tail options.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style does not write information to binary restart +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. +

    +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions: -The Lennard-Jones parameters $\epsilon$ and $\sigma$ are set to unity. -The pair sph/lj style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    +

    As noted above, the Lennard-Jones parameters epsilon and sigma are set +to unity. +

    +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    @@ -64,9 +72,15 @@ more info.

    Default: none

    -

    (Ree1980) F. H. Ree. Analytic representation of thermodynamic data for the Lennard-Jones fluid. -The Journal of Chemical Physics, 73(10):5401, 1980. +


    + + + +

    (Ree) Ree, Journal of Chemical Physics, 73, 5401 (1980).

    -

    (Monaghan1983) J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. + + +

    (Monaghan) Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983).

    diff --git a/doc/pair_sph_lj.txt b/doc/pair_sph_lj.txt index d5fde5843c..8498841131 100644 --- a/doc/pair_sph_lj.txt +++ b/doc/pair_sph_lj.txt @@ -15,46 +15,53 @@ pair_style sph/lj :pre [Examples:] pair_style sph/lj -pair_coeff * * 1.0 2.4 +pair_coeff * * 1.0 2.4 :pre [Description:] -The sph/lj style computes pressure forces between particles according to -the Lennard-Jones equation of state, which is computed according to -Ree's 1980 polynomial fit (Ree1980). The Lennard-Jones parameters -$\epsilon$ and $\sigma$ are set to unity. This pair style also computes +The sph/lj style computes pressure forces between particles according +to the Lennard-Jones equation of state, which is computed according to +Ree's 1980 polynomial fit "(Ree)"_#Ree. The Lennard-Jones parameters +epsilon and sigma are set to unity. This pair style also computes Monaghan's artificial viscosity to prevent particles from -interpentrating (Monaghan1983). +interpentrating "(Monaghan)"_#Monoghan. +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. nu artificial viscosity (no units) -h kernel function cutoff (distance units) +h kernel function cutoff (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all +This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. -This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style does not write information to "binary restart +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. + +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The Lennard-Jones parameters $\epsilon$ and $\sigma$ are set to unity. -The {pair sph/lj} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. + +As noted above, the Lennard-Jones parameters epsilon and sigma are set +to unity. + +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] @@ -62,9 +69,11 @@ more info. [Default:] none -[(Ree1980)] F. H. Ree. Analytic representation of thermodynamic data for the Lennard-Jones fluid. -The Journal of Chemical Physics, 73(10):5401, 1980. - -[(Monaghan1983)] J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. +:line +:link(Ree) +[(Ree)] Ree, Journal of Chemical Physics, 73, 5401 (1980). +:link(Monoghan) +[(Monaghan)] Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983). diff --git a/doc/pair_sph_rhosum.html b/doc/pair_sph_rhosum.html index 1a46024aab..7e3f38a91a 100644 --- a/doc/pair_sph_rhosum.html +++ b/doc/pair_sph_rhosum.html @@ -13,47 +13,52 @@
  • Syntax:

    -
    pair_style sph/rhosum nstep 
    +
    pair_style sph/rhosum Nstep 
     
    -

    nstep = timestep interval -

    +
    • Nstep = timestep interval +

    Examples:

    -

    pair_style sph/rhosum 10 -pair_coeff * * 2.4 -

    +
    pair_style sph/rhosum 10
    +pair_coeff * * 2.4 
    +

    Description:

    -

    The sph/rhosum style computes the local particle mass density rho by kernel function interpolation, -see the SPH-USER documentation. +

    The sph/rhosum style computes the local particle mass density rho for +SPH particles by kernel function interpolation, every Nstep timesteps. +

    +

    See this PDF guide to using SPH in +LAMMPS.

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    h (distance units) -

    +
    • h (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all +

    This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly.

    -

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +

    This style does not support the pair_modify +shift, table, and tail options.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style does not write information to binary restart +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. +

    +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions:

    -

    The pair sph/rhosum style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    diff --git a/doc/pair_sph_rhosum.txt b/doc/pair_sph_rhosum.txt index 8824f89925..352e717f76 100644 --- a/doc/pair_sph_rhosum.txt +++ b/doc/pair_sph_rhosum.txt @@ -10,47 +10,52 @@ pair_style sph/rhosum command :h3 [Syntax:] -pair_style sph/rhosum nstep :pre +pair_style sph/rhosum Nstep :pre -nstep = timestep interval +Nstep = timestep interval :ul [Examples:] pair_style sph/rhosum 10 -pair_coeff * * 2.4 +pair_coeff * * 2.4 :pre [Description:] -The sph/rhosum style computes the local particle mass density rho by kernel function interpolation, -see the SPH-USER documentation. +The sph/rhosum style computes the local particle mass density rho for +SPH particles by kernel function interpolation, every Nstep timesteps. + +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. -h (distance units) +h (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all +This style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. -This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style does not write information to "binary restart +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. + +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The {pair sph/rhosum} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] diff --git a/doc/pair_sph_taitwater.html b/doc/pair_sph_taitwater.html index d2bc4c54a4..1d43a15374 100644 --- a/doc/pair_sph_taitwater.html +++ b/doc/pair_sph_taitwater.html @@ -17,49 +17,59 @@

    Examples:

    -

    pair_style sph/taitwater -pair_coeff * * 1000.0 1430.0 1.0 2.4 -

    +
    pair_style sph/taitwater
    +pair_coeff * * 1000.0 1430.0 1.0 2.4 
    +

    Description:

    -

    The sph/taitwater style computes pressure forces between particles according to Tait's equation of state, -\beginequation +

    The sph/taitwater style computes pressure forces between SPH particles +according to Tait's equation of state: +

    +

    \beginequation p = B (\frac\rho\rho_0)^\gamma - 1, \endequation -where $\gamma=7$ and $B=c_0^2 \rho_0 / \gamma$, with $\rho_0$ being the reference density and $c_0$ the reference speed of sound. -This pair style also computes Monaghan's artificial viscosity to prevent particles from interpentrating (Monaghan1983). +

    +

    where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the +reference density and c_0 the reference speed of sound. +

    +

    This pair style also computes Monaghan's artificial viscosity to +prevent particles from interpentrating (Monaghan). +

    +

    See this PDF guide to using SPH in +LAMMPS.

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    rho0 reference density (mass/volume units) -c0 reference soundspeed (distance/time units) -nu artificial viscosity (no units) -h kernel function cutoff (distance units) -

    +
    • rho0 reference density (mass/volume units) +
    • c0 reference soundspeed (distance/time units) +
    • nu artificial viscosity (no units) +
    • h kernel function cutoff (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all -I,J pairs must be specified explicitly. Additionally, because rho0 and c0 are defined on a per-type basis, -an I,I as well a J,J coefficients line must be specified prior to specifying an I,J interaction. +

    This style does not support mixing. Thus, coefficients for all +I,J pairs must be specified explicitly. +

    +

    This style does not support the pair_modify +shift, table, and tail options.

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions:

    -

    The pair sph/taitwater style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    @@ -67,6 +77,11 @@ more info.

    Default: none

    -

    (Monaghan1983) J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. +


    + + + +

    (Monaghan) Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983).

    diff --git a/doc/pair_sph_taitwater.txt b/doc/pair_sph_taitwater.txt index b064bb77ff..bb00aeffb1 100644 --- a/doc/pair_sph_taitwater.txt +++ b/doc/pair_sph_taitwater.txt @@ -15,17 +15,25 @@ pair_style sph/taitwater :pre [Examples:] pair_style sph/taitwater -pair_coeff * * 1000.0 1430.0 1.0 2.4 +pair_coeff * * 1000.0 1430.0 1.0 2.4 :pre [Description:] -The sph/taitwater style computes pressure forces between particles according to Tait's equation of state, +The sph/taitwater style computes pressure forces between SPH particles +according to Tait's equation of state: + \begin{equation} p = B [(\frac{\rho}{\rho_0})^{\gamma} - 1], \end{equation} -where $\gamma=7$ and $B=c_0^2 \rho_0 / \gamma$, with $\rho_0$ being the reference density and $c_0$ the reference speed of sound. -This pair style also computes Monaghan's artificial viscosity to prevent particles from interpentrating (Monaghan1983). +where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the +reference density and c_0 the reference speed of sound. + +This pair style also computes Monaghan's artificial viscosity to +prevent particles from interpentrating "(Monaghan)"_#Monaghan. + +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples @@ -34,30 +42,31 @@ above. rho0 reference density (mass/volume units) c0 reference soundspeed (distance/time units) nu artificial viscosity (no units) -h kernel function cutoff (distance units) +h kernel function cutoff (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all -I,J pairs must be specified explicitly. Additionally, because rho0 and c0 are defined on a per-type basis, -an I,I as well a J,J coefficients line must be specified prior to specifying an I,J interaction. +This style does not support mixing. Thus, coefficients for all +I,J pairs must be specified explicitly. + +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The {pair sph/taitwater} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] @@ -65,5 +74,8 @@ more info. [Default:] none -[(Monaghan1983)] J. J. Monaghan and R. A. Gingold, “Shock simulation by the particle method SPH,” Journal of Computational Physics, vol. 52, no. 2, pp. 374-389, Nov. 1983. +:line +:link(Monoghan) +[(Monaghan)] Monaghan and Gingold, Journal of Computational Physics, +52, 374-389 (1983). diff --git a/doc/pair_sph_taitwater_morris.html b/doc/pair_sph_taitwater_morris.html index 9eabe44b42..94b95fa71c 100644 --- a/doc/pair_sph_taitwater_morris.html +++ b/doc/pair_sph_taitwater_morris.html @@ -17,49 +17,58 @@

    Examples:

    -

    pair_style sph/taitwater/morris -pair_coeff * * 1000.0 1430.0 1.0 2.4 -

    +
    pair_style sph/taitwater/morris
    +pair_coeff * * 1000.0 1430.0 1.0 2.4 
    +

    Description:

    -

    The sph/taitwater/morris style computes pressure forces between particles according to Tait's equation of state, -\beginequation +

    The sph/taitwater/morris style computes pressure forces between SPH +particles according to Tait's equation of state: +

    +

    \beginequation p = B (\frac\rho\rho_0)^\gamma - 1, \endequation -where $\gamma=7$ and $B=c_0^2 \rho_0 / \gamma$, with $\rho_0$ being the reference density and $c_0$ the reference speed of sound. -This pair style also computes laminar viscosity (Morris1997). +

    +

    where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the +reference density and c_0 the reference speed of sound. +

    +

    This pair style also computes laminar viscosity (Morris). +

    +

    See this PDF guide to using SPH in +LAMMPS.

    The following coefficients must be defined for each pair of atoms types via the pair_coeff command as in the examples above.

    -

    rho0 reference density (mass/volume units) -c0 reference soundspeed (distance/time units) -nu dynamic viscosity (mass*distance/time units) -h kernel function cutoff (distance units) -

    +
    • rho0 reference density (mass/volume units) +
    • c0 reference soundspeed (distance/time units) +
    • nu dynamic viscosity (mass*distance/time units) +
    • h kernel function cutoff (distance units) +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    -

    These pair styles do not support mixing. Thus, coefficients for all -I,J pairs must be specified explicitly. Additionally, because rho0 and c0 are defined on a per-type basis, -an I,I as well a J,J coefficients line must be specified prior to specifying an I,J interaction. +

    This style does not support mixing. Thus, coefficients for all +I,J pairs must be specified explicitly. +

    +

    This style does not support the pair_modify +shift, table, and tail options.

    This style does not write information to binary restart -files, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +files. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file.

    -

    These styles can only be used via the pair keyword of the run_style -respa command. They do not support the inner, +

    This style can only be used via the pair keyword of the run_style +respa command. It does not support the inner, middle, outer keywords.

    Restrictions:

    -

    The pair sph/taitwater/morris style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the Making LAMMPS section for -more info. +

    This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the Making +LAMMPS section for more info.

    Related commands:

    @@ -67,6 +76,10 @@ more info.

    Default: none

    -

    (Morris1997) J.P. Morris, P.J. Fox, and Y. Zhu. Modeling Low Reynolds Number Incompressible Flows Using SPH. Journal of Computational Physics, 136:214–226, 1997. +


    + + + +

    (Morris) Morris, Fox, Zhu, J Comp Physics, 136, 214–226 (1997).

    diff --git a/doc/pair_sph_taitwater_morris.txt b/doc/pair_sph_taitwater_morris.txt index df07fd9650..836440915f 100644 --- a/doc/pair_sph_taitwater_morris.txt +++ b/doc/pair_sph_taitwater_morris.txt @@ -15,17 +15,24 @@ pair_style sph/taitwater/morris :pre [Examples:] pair_style sph/taitwater/morris -pair_coeff * * 1000.0 1430.0 1.0 2.4 +pair_coeff * * 1000.0 1430.0 1.0 2.4 :pre [Description:] -The sph/taitwater/morris style computes pressure forces between particles according to Tait's equation of state, +The sph/taitwater/morris style computes pressure forces between SPH +particles according to Tait's equation of state: + \begin{equation} p = B [(\frac{\rho}{\rho_0})^{\gamma} - 1], \end{equation} -where $\gamma=7$ and $B=c_0^2 \rho_0 / \gamma$, with $\rho_0$ being the reference density and $c_0$ the reference speed of sound. -This pair style also computes laminar viscosity (Morris1997). +where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the +reference density and c_0 the reference speed of sound. + +This pair style also computes laminar viscosity "(Morris)"_#Morris. + +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples @@ -34,30 +41,31 @@ above. rho0 reference density (mass/volume units) c0 reference soundspeed (distance/time units) nu dynamic viscosity (mass*distance/time units) -h kernel function cutoff (distance units) +h kernel function cutoff (distance units) :ul :line [Mixing, shift, table, tail correction, restart, rRESPA info]: -These pair styles do not support mixing. Thus, coefficients for all -I,J pairs must be specified explicitly. Additionally, because rho0 and c0 are defined on a per-type basis, -an I,I as well a J,J coefficients line must be specified prior to specifying an I,J interaction. +This style does not support mixing. Thus, coefficients for all +I,J pairs must be specified explicitly. + +This style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. This style does not write information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do need -to be specified in an input script that reads a restart file. +files"_restart.html. Thus, you need to re-specify the pair_style and +pair_coeff commands in an input script that reads a restart file. -These styles can only be used via the {pair} keyword of the "run_style -respa"_run_style.html command. They do not support the {inner}, +This style can only be used via the {pair} keyword of the "run_style +respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. [Restrictions:] -The {pair sph/taitwater/morris} style is part of the "USER-SPH" package. It is -only enabled if LAMMPS was built with that package (which it is by -default). See the "Making LAMMPS"_Section_start.html#2_3 section for -more info. +This pair style is part of the USER-SPH package. It is only enabled +if LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] @@ -65,6 +73,9 @@ more info. [Default:] none -[(Morris1997)] J.P. Morris, P.J. Fox, and Y. Zhu. Modeling Low Reynolds Number Incompressible Flows Using SPH. Journal of Computational Physics, 136:214–226, 1997. +:line + +:link(Morris) +[(Morris)] Morris, Fox, Zhu, J Comp Physics, 136, 214–226 (1997). From b585c6d09526d703ce679c65d6cd7c1c67c9028e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Sat, 27 Aug 2011 21:18:57 +0000 Subject: [PATCH 066/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6844 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_sph_ideal.jpg | Bin 0 -> 911 bytes doc/Eqs/pair_sph_ideal.tex | 9 +++++++++ doc/Eqs/pair_sph_tait.jpg | Bin 0 -> 1465 bytes doc/Eqs/pair_sph_tait.tex | 9 +++++++++ doc/pair_sph_idealgas.html | 6 ++---- doc/pair_sph_idealgas.txt | 4 +--- doc/pair_sph_taitwater.html | 6 ++---- doc/pair_sph_taitwater.txt | 4 +--- doc/pair_sph_taitwater_morris.html | 6 ++---- doc/pair_sph_taitwater_morris.txt | 4 +--- 10 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 doc/Eqs/pair_sph_ideal.jpg create mode 100644 doc/Eqs/pair_sph_ideal.tex create mode 100644 doc/Eqs/pair_sph_tait.jpg create mode 100644 doc/Eqs/pair_sph_tait.tex diff --git a/doc/Eqs/pair_sph_ideal.jpg b/doc/Eqs/pair_sph_ideal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad9760d5eca16644483943775916dbf321b4ceaa GIT binary patch literal 911 zcmV;A191HR*#F=F5K2Z#MgRc;0RTtG1Oo*G1Ox>I1qKHU2nPoT z2M-Gi2@DYr5)u&)5fKv>92XN58Wj-{7$F!M9UUJZ9}^cMBqAOp93CGY|G)qX2mmGk zZ~*}k0RO}Q8~_0T0s{a80000000000000041p)>K0RssC!~iuA00IF70RjUA1`7ZH z000000RjU61O*Wi1|bt7K?f8uVHG1nQDSj2G-Yyjf{~Jyv*iEU00;pA002J#`!1BF zDN0h5r722Ml&Ba?rM_a;OUo_2sF~u9UrBf|MrHgwlz@KLwl)YReJNGB%;q}`)@y$A zA-uVc))KHgsggztps*TUlj=ohb(FWY%vs}ZHyht8i)TNhBcSBb{`U}A4^Xat$*J_E zD~$CPLoaWN>&x7CP-LgSwZ4xNgn(TU8)W2)77P?@@bP98DjF${se*zj9^geq(l~8+G{X?g}i7~(LTFcsjC^}wPweKm^ zc76|iA2%eEUw_p!yZLPTR;|{(L6^R=>x=wV{me4rBuqC?!vw_y`8JIkn*py7c(X?z z2HJrWooS6&bd}bBI}_*f*%6FcbMrxK7`kv$2rgO`w=jSZyNHQqV#IT8Yl!30tHbgr z!3b8@l##FxRT=OSi}CW_bet z04QLiW&16_w| lx=e04G7XSSeWKnt(_9EtNPBC$YjrA=r722Ml%*+3|Jhe&e`5du literal 0 HcmV?d00001 diff --git a/doc/Eqs/pair_sph_ideal.tex b/doc/Eqs/pair_sph_ideal.tex new file mode 100644 index 0000000000..91c64f00bc --- /dev/null +++ b/doc/Eqs/pair_sph_ideal.tex @@ -0,0 +1,9 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + p = (\gamma - 1) \rho e +$$ + +\end{document} diff --git a/doc/Eqs/pair_sph_tait.jpg b/doc/Eqs/pair_sph_tait.jpg new file mode 100644 index 0000000000000000000000000000000000000000..96adab38e056e574a29e441af6d122d4c69ece73 GIT binary patch literal 1465 zcmV;q1xEV+*#F=F5K2Z#MgRc;0RTtG1Oo*G1Ox>I1qKHU2nPoT z2M-Gi2@DYr5)u&)5fKv>92XN58Wj-{7$F!M9UUJZ9}^cMBqAOp93CGY|G)qX2mm?& ziva-<0RO}Q8vp?S0|5a60RR9100000000041qKHK0|@`b05}i;0R#d80s{mG1_uBD z0000100IL91rZVkAqNvN6e2QV6&684QIV7vBP2sraaUr2gVEE}|Jncu0RaF2KLGuf zh=_=Yh=_=Yh=_=YiWYk*O9_L&n#oJ#(xF;QR%F)rM;l9=b@BkL*G~05X2(-vaQTWg ztIL(cPn8fv9nO!JBn|SUaU?y*+CCr}Hxv61Mz%fDISPRuqV4&q%Df#4s*W9{x1FR%KB-443w`~^(F#>bI;yBFT? zD_+e6Uty3PILj;p`*QyPN&P35y^!jRt$O#yTLT4nOgGCIKZ!1oOA{Wz8zWlL86*#N z&U1Mawz8|F^Ed2cdJhWQ6G=Wt4fLi$%&&9gF~=Ms&E!vKK3Un^{np3^yB6B`t%8;}c0P*V7lW-wDQ7DAtX#-hiIB-=!D(=f zn=NBQKxY6#|8uwysP{>*KYOqIMM$1@$=b0pwytYB*vFC_mH0~|r;qNUvFB1t&P7u9}kdJlG zX>bST0UP|nzzptBFW{D6s4UOqWTC5(d~#HCp$vR4nXDiO6WfDMi9bEAgowHJV%>>+ zVva0!DfiAF2>TN(gX*qUuQ5eR*4HrAVuYIgs z6mtInwS1pcTESkDtT>2q*xnOC-*U+%hiJ$($co@^Ujnu0d@by4obFE`BCjrIA?<>c zF54?KMI2xg_oR21&E$6E?G5XbvV9F1sgm&K{D6oq^ogL?pFucfX_(KMa~V6o+CIDO ztIhPzYax`HHQmg8q2?bf#~ckF+jCpFsnZ%V11ABkhy@o%U} zY1rRTUL*1|Xsg+t=;CwP6XkP8!x%>0@*5z2Wpi5i{FW!cPNK(Uaq`l$9zQ7|YvhgK zi5)zR(PNxG7Y(kOh@n-);;Lk=Wa{H7L3-F|vt~FN*=7yj5cdJMYiCdl@zx@hK^U(Yk;KKog3c}{kk*E~`gZhHJx`ds^{)xin5le=7vrAgyCH$@f~-6m zc!RJW`6Y>?kRx7U^#Nu&C&a^h32N2)?wSmJ{{UpMc#y*OOL6elkT4B6x-TYIk;H0I z#2=oMen^ zWPa=(#dy8YR427{mFAAFGW?Wevr0HLH&xBxBXA>wOJj|sXn-5rMD1)*5fKp)5fKp) T5fKp)5fKp)5fKp)5r6;L*o%yw literal 0 HcmV?d00001 diff --git a/doc/Eqs/pair_sph_tait.tex b/doc/Eqs/pair_sph_tait.tex new file mode 100644 index 0000000000..4e1fa9cfed --- /dev/null +++ b/doc/Eqs/pair_sph_tait.tex @@ -0,0 +1,9 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + p = B [(\frac{\rho}{\rho_0})^{\gamma} - 1] +$$ + +\end{document} diff --git a/doc/pair_sph_idealgas.html b/doc/pair_sph_idealgas.html index 8d5ac22a2d..4d45b2959c 100644 --- a/doc/pair_sph_idealgas.html +++ b/doc/pair_sph_idealgas.html @@ -25,10 +25,8 @@ pair_coeff * * 1.0 2.4

    The sph/idealgas style computes pressure forces between particles according to the ideal gas equation of state:

    -

    \beginequation -p = (\gamma - 1) \rho e, -\endequation -

    +
    +

    where gamma = 1.4 is the heat capacity ratio, rho is the local density, and e is the internal energy per unit mass. This pair style also computes Monaghan's artificial viscosity to prevent particles diff --git a/doc/pair_sph_idealgas.txt b/doc/pair_sph_idealgas.txt index ad8ef6a0c8..f28d26265e 100644 --- a/doc/pair_sph_idealgas.txt +++ b/doc/pair_sph_idealgas.txt @@ -22,9 +22,7 @@ pair_coeff * * 1.0 2.4 :pre The sph/idealgas style computes pressure forces between particles according to the ideal gas equation of state: -\begin{equation} -p = (\gamma - 1) \rho e, -\end{equation} +:c,image(Eqs/pair_sph_ideal.jpg) where gamma = 1.4 is the heat capacity ratio, rho is the local density, and e is the internal energy per unit mass. This pair style diff --git a/doc/pair_sph_taitwater.html b/doc/pair_sph_taitwater.html index 1d43a15374..7c350f2f37 100644 --- a/doc/pair_sph_taitwater.html +++ b/doc/pair_sph_taitwater.html @@ -25,10 +25,8 @@ pair_coeff * * 1000.0 1430.0 1.0 2.4

    The sph/taitwater style computes pressure forces between SPH particles according to Tait's equation of state:

    -

    \beginequation -p = B (\frac\rho\rho_0)^\gamma - 1, -\endequation -

    +
    +

    where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the reference density and c_0 the reference speed of sound.

    diff --git a/doc/pair_sph_taitwater.txt b/doc/pair_sph_taitwater.txt index bb00aeffb1..5f6fbeb5b4 100644 --- a/doc/pair_sph_taitwater.txt +++ b/doc/pair_sph_taitwater.txt @@ -22,9 +22,7 @@ pair_coeff * * 1000.0 1430.0 1.0 2.4 :pre The sph/taitwater style computes pressure forces between SPH particles according to Tait's equation of state: -\begin{equation} -p = B [(\frac{\rho}{\rho_0})^{\gamma} - 1], -\end{equation} +:c,image(Eqs/pair_sph_tait.jpg) where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the reference density and c_0 the reference speed of sound. diff --git a/doc/pair_sph_taitwater_morris.html b/doc/pair_sph_taitwater_morris.html index 94b95fa71c..4abffb4c53 100644 --- a/doc/pair_sph_taitwater_morris.html +++ b/doc/pair_sph_taitwater_morris.html @@ -25,10 +25,8 @@ pair_coeff * * 1000.0 1430.0 1.0 2.4

    The sph/taitwater/morris style computes pressure forces between SPH particles according to Tait's equation of state:

    -

    \beginequation -p = B (\frac\rho\rho_0)^\gamma - 1, -\endequation -

    +
    +

    where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the reference density and c_0 the reference speed of sound.

    diff --git a/doc/pair_sph_taitwater_morris.txt b/doc/pair_sph_taitwater_morris.txt index 836440915f..8bedfd4991 100644 --- a/doc/pair_sph_taitwater_morris.txt +++ b/doc/pair_sph_taitwater_morris.txt @@ -22,9 +22,7 @@ pair_coeff * * 1000.0 1430.0 1.0 2.4 :pre The sph/taitwater/morris style computes pressure forces between SPH particles according to Tait's equation of state: -\begin{equation} -p = B [(\frac{\rho}{\rho_0})^{\gamma} - 1], -\end{equation} +:c,image(Eqs/pair_sph_tait.jpg) where gamma = 7 and B = c_0^2 rho_0 / gamma, with rho_0 being the reference density and c_0 the reference speed of sound. From 4ebd4967a71d0b75cd5b127bf6c1225a32b4c93b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Sat, 27 Aug 2011 21:50:07 +0000 Subject: [PATCH 067/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6848 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_intro.txt | 2 +- doc/compute_ackland_atom.txt | 11 +++++++---- doc/compute_meso_e_atom.txt | 11 +++++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 8a53b89bbd..9dde846b6d 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -139,7 +139,7 @@ commands) embedded ion method (EIM), ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB electron force field (eFF, AWPMD) coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO - mesoscopic potentials: granular, Peridynamics + mesoscopic potentials: granular, Peridynamics, SPH bond potentials: harmonic, FENE, Morse, nonlinear, class 2, \ quartic (breakable) angle potentials: harmonic, CHARMM, cosine, cosine/squared, cosine/periodic, \ diff --git a/doc/compute_ackland_atom.txt b/doc/compute_ackland_atom.txt index 8722cf30e0..5a9dcebbad 100644 --- a/doc/compute_ackland_atom.txt +++ b/doc/compute_ackland_atom.txt @@ -48,10 +48,10 @@ which computes this quantity.- [Output info:] -This compute calculates a scalar quantity for each atom, which can be -accessed by any command that uses per-atom values from a compute as -input. See "this section"_Section_howto.html#howto_15 for an overview -of LAMMPS output options. +This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +"this section"_Section_howto.html#howto_15 for an overview of LAMMPS +output options. [Restrictions:] @@ -59,6 +59,9 @@ This compute is part of the USER-MISC package. It is only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. +The per-atom vector values will be unitless since they are the +integers defined above. + [Related commands:] "compute centro/atom"_compute_centro_atom.html diff --git a/doc/compute_meso_e_atom.txt b/doc/compute_meso_e_atom.txt index 55d2d0d6c3..b85115da49 100644 --- a/doc/compute_meso_e_atom.txt +++ b/doc/compute_meso_e_atom.txt @@ -28,15 +28,18 @@ The internal energy is the energy associated with the internal degrees of freedom of a mesoscopic particles, e.g. a Smooth-Particle Hydrodynamics particle. +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. + The value of the internal energy will be 0.0 for atoms not in the specified compute group. [Output info:] -This compute calculates a scalar quantity for each atom, which can be -accessed by any command that uses per-atom values from a compute as -input. See "this section"_Section_howto.html#4_15 for an overview of -LAMMPS output options. +This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +"this section"_Section_howto.html#4_15 for an overview of LAMMPS +output options. The per-atom vector values will be in energy "units"_units.html. From cf62e09a95b396a31f4d0b19985830a512421397 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Sat, 27 Aug 2011 21:53:22 +0000 Subject: [PATCH 068/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6849 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 37aa905581..e41eb3ca21 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "26 Aug 2011" +#define LAMMPS_VERSION "27 Aug 2011" From 0af78ca0621290092b3aa9306f4b8d5ee533ae15 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Sat, 27 Aug 2011 22:24:32 +0000 Subject: [PATCH 069/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6851 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_intro.html | 2 +- doc/Section_packages.html | 4 +++- doc/Section_packages.txt | 1 + doc/compute_ackland_atom.html | 11 +++++++---- doc/compute_meso_e_atom.html | 11 +++++++---- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/doc/Section_intro.html b/doc/Section_intro.html index ec4e458657..b77261945d 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -142,7 +142,7 @@ commands)
  • manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), embedded ion method (EIM), ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB
  • electron force field (eFF, AWPMD)
  • coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO -
  • mesoscopic potentials: granular, Peridynamics +
  • mesoscopic potentials: granular, Peridynamics, SPH
  • bond potentials: harmonic, FENE, Morse, nonlinear, class 2, quartic (breakable)
  • angle potentials: harmonic, CHARMM, cosine, cosine/squared, cosine/periodic, class 2 (COMPASS)
  • dihedral potentials: harmonic, CHARMM, multi-harmonic, helix, class 2 (COMPASS), OPLS diff --git a/doc/Section_packages.html b/doc/Section_packages.html index 219fd21278..64de534faa 100644 --- a/doc/Section_packages.html +++ b/doc/Section_packages.html @@ -98,7 +98,7 @@ E.g. "peptide" refers to the examples/peptide directory. USER-EFF electron force field Andres Jaramillo-Botero (Caltech) pair_style eff/cut USER/eff eff - USER-EWALDN Ewald for 1/R^n Pieter in' t Veld (BASF) kspace_style - - - USER-REAXC C version of ReaxFF Metin Aktulga (LBNL) pair_style reaxc reax - - -USER-SPH smoothed particle hydrodynamics Georg Ganzenmuller (EMI) SPH_LAMMPS_userguide.pdf USER/sph sph - +USER-SPH smoothed particle hydrodynamics Georg Ganzenmuller (EMI) SPH_LAMMPS_userguide.pdf USER/sph sph - @@ -108,6 +108,8 @@ E.g. "peptide" refers to the examples/peptide directory. + +

    The "Authors" column lists a name(s) if a specific person is responible for creating and maintaining the package.

    diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt index d033100919..356611af93 100644 --- a/doc/Section_packages.txt +++ b/doc/Section_packages.txt @@ -96,6 +96,7 @@ USER-SPH, smoothed particle hydrodynamics, Georg Ganzenmuller (EMI), "SPH_LAMMPS :link(atc,http://lammps.sandia.gov/pictures.html#atc) :link(cg,http://lammps.sandia.gov/pictures.html#cg) :link(eff,http://lammps.sandia.gov/movies.html#eff) +:link(sph,http://lammps.sandia.gov/movies.html#sph) The "Authors" column lists a name(s) if a specific person is responible for creating and maintaining the package. diff --git a/doc/compute_ackland_atom.html b/doc/compute_ackland_atom.html index 60730075ee..16ad975e88 100644 --- a/doc/compute_ackland_atom.html +++ b/doc/compute_ackland_atom.html @@ -51,10 +51,10 @@ which computes this quantity.-

    Output info:

    -

    This compute calculates a scalar quantity for each atom, which can be -accessed by any command that uses per-atom values from a compute as -input. See this section for an overview -of LAMMPS output options. +

    This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +this section for an overview of LAMMPS +output options.

    Restrictions:

    @@ -62,6 +62,9 @@ of LAMMPS output options. LAMMPS was built with that package. See the Making LAMMPS section for more info.

    +

    The per-atom vector values will be unitless since they are the +integers defined above. +

    Related commands:

    compute centro/atom diff --git a/doc/compute_meso_e_atom.html b/doc/compute_meso_e_atom.html index 4d7859e58d..69d903799b 100644 --- a/doc/compute_meso_e_atom.html +++ b/doc/compute_meso_e_atom.html @@ -31,15 +31,18 @@ for each atom in a group. of freedom of a mesoscopic particles, e.g. a Smooth-Particle Hydrodynamics particle.

    +

    See this PDF guide to using SPH in +LAMMPS. +

    The value of the internal energy will be 0.0 for atoms not in the specified compute group.

    Output info:

    -

    This compute calculates a scalar quantity for each atom, which can be -accessed by any command that uses per-atom values from a compute as -input. See this section for an overview of -LAMMPS output options. +

    This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +this section for an overview of LAMMPS +output options.

    The per-atom vector values will be in energy units.

    From 92ab39a01a4aca3c56a4db2e8b2da0b8e4520160 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 29 Aug 2011 14:08:38 +0000 Subject: [PATCH 070/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6852 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_ave_spatial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp index f066615e8d..e1b47e5015 100644 --- a/src/fix_ave_spatial.cpp +++ b/src/fix_ave_spatial.cpp @@ -310,7 +310,7 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : if (ndim == 1) fprintf(fp,"# Bin Coord Ncount"); else if (ndim == 2) fprintf(fp,"# Bin Coord1 Coord2 Ncount"); else if (ndim == 3) fprintf(fp,"# Bin Coord1 Coord2 Coord3 Ncount"); - for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[9+i]); + for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[6+3*ndim+i]); fprintf(fp,"\n"); } } From 5e2892aaccefa4ce367f01364dd0d6c1257bea55 Mon Sep 17 00:00:00 2001 From: athomps Date: Mon, 29 Aug 2011 18:44:24 +0000 Subject: [PATCH 071/246] Added pair_style lj/cubic git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6854 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_lj_cubic.html | 98 ++++++++++++++++++++++++++++++++++++++++++ doc/pair_lj_cubic.txt | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 doc/pair_lj_cubic.html create mode 100644 doc/pair_lj_cubic.txt diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html new file mode 100644 index 0000000000..2fb0464c19 --- /dev/null +++ b/doc/pair_lj_cubic.html @@ -0,0 +1,98 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    pair_style lj/cubic command +

    +

    Syntax: +

    +
    pair_style lj/cubic 
    +
    +

    Examples: +

    +
    pair_style lj/cubic
    +pair_coeff * * 1.0 0.8908987 
    +
    +

    Description: +

    +

    The lj/cubic style computes a truncated LJ interaction potential whose +energy and force are continuous everywhere. This is +achieved by replacing the LJ function outside the inflection point with +a cubic function of distance, so that both the energy and force are +continuous at the inflection point, and go to zero at the +cutoff distance. The LJ potential inside the inflection point is +unchanged. The location of the inflection point rs is defined +by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance +is defined by rcut/rs = 67/48. +

    +

    This potential is commonly used to study the shock compression +of FCC solids, as in the paper by Holian and Ravelo (Holian). +

    +

    The following coefficients must be defined for each pair of atoms +types via the pair_coeff command as in the example +above, or in the data file or restart files read by the +read_data or read_restart +commands, or by mixing as described below: +

    +
    • epsilon (energy units) +
    • sigma (distance units) +
    +

    Note that sigma is defined in the LJ formula as the zero-crossing +distance for the potential, not as the energy minimum, which +is located at 2^(1/6)*sigma. In the above example, sigma = 0.8908987, +so the energy minimum is located at r = 1. +

    +
    + +

    Mixing, shift, table, tail correction, restart, rRESPA info: +

    +

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of the lj/cut pair styles can be mixed. +The default mix value is geometric. See the "pair_modify" command +for details. +

    +

    The lj/cubic pair style does not support the +pair_modify shift option, +since pair interaction is already smoothed to 0.0 at the +cutoff. +

    +

    The pair_modify table option is not relevant +for this pair style. +

    +

    The lj/cubic pair style does not support the +pair_modify tail option for adding long-range tail +corrections to energy and pressure, since there are no corrections for +a potential that goes to 0.0 at the cutoff. +

    +

    The lj/cubic pair style writes its information to binary +restart files, so pair_style and pair_coeff commands do +not need to be specified in an input script that reads a restart file. +

    +

    The lj/cubic pair style can only be used via the pair +keyword of the run_style respa command. It does not +support the inner, middle, outer keywords. +

    +
    + +

    Restrictions: none +

    +

    Related commands: +

    +

    pair_coeff +

    +

    Default: none +

    +
    + + + +

    (Holian) Holian and Ravelo, Phys Rev B, 51, 11275 (1995). +

    + diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt new file mode 100644 index 0000000000..f0a864c609 --- /dev/null +++ b/doc/pair_lj_cubic.txt @@ -0,0 +1,92 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style lj/cubic command :h3 + +[Syntax:] + +pair_style lj/cubic :pre + +[Examples:] + +pair_style lj/cubic +pair_coeff * * 1.0 0.8908987 :pre + +[Description:] + +The {lj/cubic} style computes a truncated LJ interaction potential whose +energy and force are continuous everywhere. This is +achieved by replacing the LJ function outside the inflection point with +a cubic function of distance, so that both the energy and force are +continuous at the inflection point, and go to zero at the +cutoff distance. The LJ potential inside the inflection point is +unchanged. The location of the inflection point rs is defined +by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance +is defined by rcut/rs = 67/48. + +This potential is commonly used to study the shock compression +of FCC solids, as in the paper by Holian and Ravelo "(Holian)"_#Holian. + +The following coefficients must be defined for each pair of atoms +types via the "pair_coeff"_pair_coeff.html command as in the example +above, or in the data file or restart files read by the +"read_data"_read_data.html or "read_restart"_read_restart.html +commands, or by mixing as described below: + +epsilon (energy units) +sigma (distance units) :ul + +Note that sigma is defined in the LJ formula as the zero-crossing +distance for the potential, not as the energy minimum, which +is located at 2^(1/6)*sigma. In the above example, sigma = 0.8908987, +so the energy minimum is located at r = 1. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of the lj/cut pair styles can be mixed. +The default mix value is {geometric}. See the "pair_modify" command +for details. + +The lj/cubic pair style does not support the +"pair_modify"_pair_modify.html shift option, +since pair interaction is already smoothed to 0.0 at the +cutoff. + +The "pair_modify"_pair_modify.html table option is not relevant +for this pair style. + +The lj/cubic pair style does not support the +"pair_modify"_pair_modify.html tail option for adding long-range tail +corrections to energy and pressure, since there are no corrections for +a potential that goes to 0.0 at the cutoff. + +The lj/cubic pair style writes its information to "binary +restart files"_restart.html, so pair_style and pair_coeff commands do +not need to be specified in an input script that reads a restart file. + +The lj/cubic pair style can only be used via the {pair} +keyword of the "run_style respa"_run_style.html command. It does not +support the {inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] none + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none + +:line + +:link(Holian) +[(Holian)] Holian and Ravelo, Phys Rev B, 51, 11275 (1995). From 688c433eb9983e9c42bef8bbca4aded12ebad291 Mon Sep 17 00:00:00 2001 From: athomps Date: Mon, 29 Aug 2011 18:54:51 +0000 Subject: [PATCH 072/246] Added pair_style lj/cubic git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6855 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_lj_cubic.cpp | 360 ++++++++++++++++++++++++++++++++++++++++++ src/pair_lj_cubic.h | 61 +++++++ 2 files changed, 421 insertions(+) create mode 100644 src/pair_lj_cubic.cpp create mode 100644 src/pair_lj_cubic.h diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp new file mode 100644 index 0000000000..97f82b39c3 --- /dev/null +++ b/src/pair_lj_cubic.cpp @@ -0,0 +1,360 @@ + +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Aidan Thompson (SNL) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_lj_cubic.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)) + +/* ---------------------------------------------------------------------- */ + +PairLJCubic::PairLJCubic(LAMMPS *lmp) : Pair(lmp) {} + +/* ---------------------------------------------------------------------- */ + +PairLJCubic::~PairLJCubic() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(cut_inner); + memory->destroy(cut_inner_sq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCubic::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,forcelj,factor_lj; + double r,t,rmin; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + 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 (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + 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]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + if (rsq <= cut_inner_sq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + } else { + r = sqrt(rsq); + rmin = sigma[itype][jtype]*rt6two; + t = (r - cut_inner[itype][jtype])/rmin; + forcelj = epsilon[itype][jtype]*(-dphids + a3*t*t/2.0)*r/rmin; + } + fpair = factor_lj*forcelj*r2inv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (eflag) { + if (rsq <= cut_inner_sq[itype][jtype]) + evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + else + evdwl = epsilon[itype][jtype]* + (phis + dphids*t - a3*t*t*t/6.0); + evdwl *= factor_lj; + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairLJCubic::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cut_inner,n+1,n+1,"pair:cut_inner"); + memory->create(cut_inner_sq,n+1,n+1,"pair:cut_inner_sq"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairLJCubic::settings(int narg, char **arg) +{ + if (narg != 0) error->all("Illegal pair_style command"); + + // 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] = 0.0; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairLJCubic::coeff(int narg, char **arg) +{ + if (narg != 4) + 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 epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + double rmin = sigma_one*rt6two; + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + cut_inner[i][j] = rmin*s; + cut[i][j] = rmin*sm; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all("Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairLJCubic::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut_inner[i][j] = mix_distance(cut_inner[i][i],cut_inner[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + cut_inner_sq[i][j] = cut_inner[i][j]*cut_inner[i][j]; + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + cut_inner[j][i] = cut_inner[i][j]; + cut_inner_sq[j][i] = cut_inner_sq[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairLJCubic::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(&epsilon[i][j],sizeof(double),1,fp); + fwrite(&sigma[i][j],sizeof(double),1,fp); + fwrite(&cut_inner[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairLJCubic::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(&epsilon[i][j],sizeof(double),1,fp); + fread(&sigma[i][j],sizeof(double),1,fp); + fread(&cut_inner[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_inner[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairLJCubic::write_restart_settings(FILE *fp) +{ + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairLJCubic::read_restart_settings(FILE *fp) +{ + int me = comm->me; + if (me == 0) { + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCubic::single(int i, int j, int itype, int jtype, + double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + double r2inv,r6inv,forcelj,philj; + double r,t; + double rmin; + + r2inv = 1.0/rsq; + if (rsq <= cut_inner_sq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + } else { + r = sqrt(rsq); + rmin = sigma[itype][jtype]*rt6two; + t = (r - cut_inner[itype][jtype])/rmin; + forcelj = epsilon[itype][jtype]*(-dphids + a3*t*t/2.0)*r/rmin; + } + fforce = factor_lj*forcelj*r2inv; + + if (rsq <= cut_inner_sq[itype][jtype]) + philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + else + philj = epsilon[itype][jtype]* + (phis + dphids*t - a3*t*t*t/6.0); + + return factor_lj*philj; +} diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h new file mode 100644 index 0000000000..25b8d90344 --- /dev/null +++ b/src/pair_lj_cubic.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cubic,PairLJCubic) + +#else + +#ifndef LMP_PAIR_LJ_CUBIC_H +#define LMP_PAIR_LJ_CUBIC_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairLJCubic : public Pair { + public: + PairLJCubic(class LAMMPS *); + virtual ~PairLJCubic(); + virtual void compute(int, int); + virtual void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + virtual double single(int, int, int, int, double, double, double, double &); + + protected: + double **cut,**cut_inner,**cut_inner_sq; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + + // LJ quantities scaled by epsilon and rmin = sigma*2^1/6 + + static const double rt6two = 1.1224621; // 2^1/6 + static const double s = 1.1086834; // inflection point = (13/7)^1/6 + static const double phis = -0.7869823; // energy at s + static const double dphids = 2.6899009; // gradient at s + static const double a3 = 27.93357; // cubic coefficient + static const double sm = 1.5475375; // cubic cutoff = s*67/48 + + void allocate(); +}; + +} + +#endif +#endif From 33b919a5b64db5067e3e01a6faedcb6dca14663d Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 18:01:33 +0000 Subject: [PATCH 073/246] Added equation for lj_cubic git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6858 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_lj_cubic.jpg | Bin 0 -> 22768 bytes doc/Eqs/pair_lj_cubic.tex | 12 ++++++++++++ doc/pair_lj_cubic.html | 34 ++++++++++++++++++++++------------ doc/pair_lj_cubic.txt | 34 ++++++++++++++++++++++------------ 4 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 doc/Eqs/pair_lj_cubic.jpg create mode 100644 doc/Eqs/pair_lj_cubic.tex diff --git a/doc/Eqs/pair_lj_cubic.jpg b/doc/Eqs/pair_lj_cubic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e52392b87e329e56e233512df0f2bdb0396444cd GIT binary patch literal 22768 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 r_c +\end{eqnarray*} + + +\end{document} diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html index 2fb0464c19..3df6c4f972 100644 --- a/doc/pair_lj_cubic.html +++ b/doc/pair_lj_cubic.html @@ -23,19 +23,29 @@ pair_coeff * * 1.0 0.8908987

    Description:

    The lj/cubic style computes a truncated LJ interaction potential whose -energy and force are continuous everywhere. This is -achieved by replacing the LJ function outside the inflection point with -a cubic function of distance, so that both the energy and force are -continuous at the inflection point, and go to zero at the -cutoff distance. The LJ potential inside the inflection point is -unchanged. The location of the inflection point rs is defined -by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance -is defined by rcut/rs = 67/48. +energy and force are continuous everywhere. +Inside the inflection point the interaction is identical to the +standard 12/6 Lennard-Jones potential. +The LJ function outside the inflection point is replaced +with a cubic function of distance. The energy, force and second +derivative are continuous at the inflection point. +The cubic coefficient A3 is chosen so +that both energy and force go to zero at the cutoff distance. +Outside the cutoff distance the energy and force are zero.

    -

    This potential is commonly used to study the shock compression +

    +
    +

    The location of the inflection point rs is defined +by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance +is defined by rc/rs = 67/48. The analytic expression for the +the cubic coefficient +A3*rmin^3/epsilon = 27.93357 is given in the paper +Holian and Ravelo (Holian). +

    +

    This potential is commonly used to study the mechanical behavior of FCC solids, as in the paper by Holian and Ravelo (Holian).

    -

    The following coefficients must be defined for each pair of atoms +

    The following coefficients must be defined for each pair of atom types via the pair_coeff command as in the example above, or in the data file or restart files read by the read_data or read_restart @@ -46,8 +56,8 @@ commands, or by mixing as described below:

    Note that sigma is defined in the LJ formula as the zero-crossing distance for the potential, not as the energy minimum, which -is located at 2^(1/6)*sigma. In the above example, sigma = 0.8908987, -so the energy minimum is located at r = 1. +is located at rmin = 2^(1/6)*sigma. In the above example, sigma = 0.8908987, +so rmin = 1.


    diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt index f0a864c609..f1dcac30be 100644 --- a/doc/pair_lj_cubic.txt +++ b/doc/pair_lj_cubic.txt @@ -20,19 +20,29 @@ pair_coeff * * 1.0 0.8908987 :pre [Description:] The {lj/cubic} style computes a truncated LJ interaction potential whose -energy and force are continuous everywhere. This is -achieved by replacing the LJ function outside the inflection point with -a cubic function of distance, so that both the energy and force are -continuous at the inflection point, and go to zero at the -cutoff distance. The LJ potential inside the inflection point is -unchanged. The location of the inflection point rs is defined -by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance -is defined by rcut/rs = 67/48. +energy and force are continuous everywhere. +Inside the inflection point the interaction is identical to the +standard 12/6 "Lennard-Jones"_pair_lj.html potential. +The LJ function outside the inflection point is replaced +with a cubic function of distance. The energy, force and second +derivative are continuous at the inflection point. +The cubic coefficient A3 is chosen so +that both energy and force go to zero at the cutoff distance. +Outside the cutoff distance the energy and force are zero. -This potential is commonly used to study the shock compression +:c,image(Eqs/pair_lj_cubic.jpg) + +The location of the inflection point rs is defined +by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance +is defined by rc/rs = 67/48. The analytic expression for the +the cubic coefficient +A3*rmin^3/epsilon = 27.93357 is given in the paper +Holian and Ravelo "(Holian)"_#Holian. + +This potential is commonly used to study the mechanical behavior of FCC solids, as in the paper by Holian and Ravelo "(Holian)"_#Holian. -The following coefficients must be defined for each pair of atoms +The following coefficients must be defined for each pair of atom types via the "pair_coeff"_pair_coeff.html command as in the example above, or in the data file or restart files read by the "read_data"_read_data.html or "read_restart"_read_restart.html @@ -43,8 +53,8 @@ sigma (distance units) :ul Note that sigma is defined in the LJ formula as the zero-crossing distance for the potential, not as the energy minimum, which -is located at 2^(1/6)*sigma. In the above example, sigma = 0.8908987, -so the energy minimum is located at r = 1. +is located at rmin = 2^(1/6)*sigma. In the above example, sigma = 0.8908987, +so rmin = 1. :line From 7d6d7628c1a1458ffb1123462abf3cfb0a402d4d Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 18:04:28 +0000 Subject: [PATCH 074/246] Added equation for lj_cubic git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6859 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_lj_cubic.jpg | Bin 22768 -> 22779 bytes doc/Eqs/pair_lj_cubic.tex | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Eqs/pair_lj_cubic.jpg b/doc/Eqs/pair_lj_cubic.jpg index e52392b87e329e56e233512df0f2bdb0396444cd..a5ff3de22c5cb7b1f8a54f829820f17e72781e16 100644 GIT binary patch delta 15147 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 SyV|9kNcXY3aEj%4_J0BIwjc=r delta 15391 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 r_c \end{eqnarray*} From 0833cc51450163ac6eb9b7fcd1224826560c9d43 Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 19:45:56 +0000 Subject: [PATCH 075/246] Added equation for lj_cubic git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6860 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_lj_cubic.html | 7 ++++--- doc/pair_lj_cubic.txt | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html index 3df6c4f972..dfef57809d 100644 --- a/doc/pair_lj_cubic.html +++ b/doc/pair_lj_cubic.html @@ -27,7 +27,7 @@ energy and force are continuous everywhere. Inside the inflection point the interaction is identical to the standard 12/6 Lennard-Jones potential. The LJ function outside the inflection point is replaced -with a cubic function of distance. The energy, force and second +with a cubic function of distance. The energy, force, and second derivative are continuous at the inflection point. The cubic coefficient A3 is chosen so that both energy and force go to zero at the cutoff distance. @@ -37,9 +37,10 @@ Outside the cutoff distance the energy and force are zero.

    The location of the inflection point rs is defined by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance -is defined by rc/rs = 67/48. The analytic expression for the +is defined by rc/rs = 67/48 or rc/sigma = 1.737.... +The analytic expression for the the cubic coefficient -A3*rmin^3/epsilon = 27.93357 is given in the paper +A3*rmin^3/epsilon = 27.93... is given in the paper by Holian and Ravelo (Holian).

    This potential is commonly used to study the mechanical behavior diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt index f1dcac30be..6e906687e8 100644 --- a/doc/pair_lj_cubic.txt +++ b/doc/pair_lj_cubic.txt @@ -24,7 +24,7 @@ energy and force are continuous everywhere. Inside the inflection point the interaction is identical to the standard 12/6 "Lennard-Jones"_pair_lj.html potential. The LJ function outside the inflection point is replaced -with a cubic function of distance. The energy, force and second +with a cubic function of distance. The energy, force, and second derivative are continuous at the inflection point. The cubic coefficient A3 is chosen so that both energy and force go to zero at the cutoff distance. @@ -34,9 +34,10 @@ Outside the cutoff distance the energy and force are zero. The location of the inflection point rs is defined by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance -is defined by rc/rs = 67/48. The analytic expression for the +is defined by rc/rs = 67/48 or rc/sigma = 1.737.... +The analytic expression for the the cubic coefficient -A3*rmin^3/epsilon = 27.93357 is given in the paper +A3*rmin^3/epsilon = 27.93... is given in the paper by Holian and Ravelo "(Holian)"_#Holian. This potential is commonly used to study the mechanical behavior From 2ac7e59bf7a59d2ba77bd653ba8e76870b0883f4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 30 Aug 2011 20:18:39 +0000 Subject: [PATCH 076/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6861 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_lj_cubic.jpg | Bin 22779 -> 5384 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/Eqs/pair_lj_cubic.jpg b/doc/Eqs/pair_lj_cubic.jpg index a5ff3de22c5cb7b1f8a54f829820f17e72781e16..25ffe2cbf8297125b258a45a9a467f70e82da3f9 100644 GIT binary patch literal 5384 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 literal 22779 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 uZ46L9ndA~Rk@Ge3J6aNMz7lgn7 From a925734a2bf03381e96045d81439713f1f1560c5 Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 20:46:40 +0000 Subject: [PATCH 077/246] Fixed problem with static const git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6862 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_lj_cubic.cpp | 9 +++++++++ src/pair_lj_cubic.h | 12 ++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp index 97f82b39c3..13f6e479e4 100644 --- a/src/pair_lj_cubic.cpp +++ b/src/pair_lj_cubic.cpp @@ -34,6 +34,15 @@ using namespace LAMMPS_NS; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) +// LJ quantities scaled by epsilon and rmin = sigma*2^1/6 + +const double PairLJCubic::rt6two = 1.1224621; // 2^1/6 +const double PairLJCubic::s = 1.1086834; // inflection point = (13/7)^1/6 +const double PairLJCubic::phis = -0.7869823; // energy at s +const double PairLJCubic::dphids = 2.6899009; // gradient at s +const double PairLJCubic::a3 = 27.93357; // cubic coefficient +const double PairLJCubic::sm = 1.5475375; // cubic cutoff = s*67/48 + /* ---------------------------------------------------------------------- */ PairLJCubic::PairLJCubic(LAMMPS *lmp) : Pair(lmp) {} diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h index 25b8d90344..f8afb8e02c 100644 --- a/src/pair_lj_cubic.h +++ b/src/pair_lj_cubic.h @@ -45,12 +45,12 @@ class PairLJCubic : public Pair { // LJ quantities scaled by epsilon and rmin = sigma*2^1/6 - static const double rt6two = 1.1224621; // 2^1/6 - static const double s = 1.1086834; // inflection point = (13/7)^1/6 - static const double phis = -0.7869823; // energy at s - static const double dphids = 2.6899009; // gradient at s - static const double a3 = 27.93357; // cubic coefficient - static const double sm = 1.5475375; // cubic cutoff = s*67/48 + static const double rt6two; // 2^1/6 + static const double s; // inflection point = (13/7)^1/6 + static const double phis; // energy at s + static const double dphids; // gradient at s + static const double a3; // cubic coefficient + static const double sm; // cubic cutoff = s*67/48 void allocate(); }; From 8ab38ece5a5fea0a1961da927938b7905bb2c9e4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 30 Aug 2011 20:54:38 +0000 Subject: [PATCH 078/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6863 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/dump_image.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dump_image.cpp b/src/dump_image.cpp index d41be6a338..717fb0a7f4 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -1502,6 +1502,7 @@ void DumpImage::write_JPG() } jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); #endif } From c54dc5a50315109c2e97b33c67e4c6f0b05c3760 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 30 Aug 2011 20:54:44 +0000 Subject: [PATCH 079/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6864 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_lj_cubic.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h index f8afb8e02c..f2fab703a6 100644 --- a/src/pair_lj_cubic.h +++ b/src/pair_lj_cubic.h @@ -27,18 +27,18 @@ namespace LAMMPS_NS { class PairLJCubic : public Pair { public: PairLJCubic(class LAMMPS *); - virtual ~PairLJCubic(); - virtual void compute(int, int); - virtual void settings(int, char **); + ~PairLJCubic(); + void compute(int, int); + void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); - virtual void write_restart_settings(FILE *); - virtual void read_restart_settings(FILE *); - virtual double single(int, int, int, int, double, double, double, double &); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + double single(int, int, int, int, double, double, double, double &); - protected: + private: double **cut,**cut_inner,**cut_inner_sq; double **epsilon,**sigma; double **lj1,**lj2,**lj3,**lj4; From 183f1b753d16269e9cbf42663cd9f839b240b5c8 Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 20:59:49 +0000 Subject: [PATCH 080/246] Fixed problem with static const git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6865 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_lj_cubic.cpp | 36 ++++++++++++++++++------------------ src/pair_lj_cubic.h | 9 --------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp index 13f6e479e4..c58df8f989 100644 --- a/src/pair_lj_cubic.cpp +++ b/src/pair_lj_cubic.cpp @@ -31,17 +31,17 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // LJ quantities scaled by epsilon and rmin = sigma*2^1/6 -const double PairLJCubic::rt6two = 1.1224621; // 2^1/6 -const double PairLJCubic::s = 1.1086834; // inflection point = (13/7)^1/6 -const double PairLJCubic::phis = -0.7869823; // energy at s -const double PairLJCubic::dphids = 2.6899009; // gradient at s -const double PairLJCubic::a3 = 27.93357; // cubic coefficient -const double PairLJCubic::sm = 1.5475375; // cubic cutoff = s*67/48 +#define RT6TWO 1.1224621 // 2^1/6 +#define SS 1.1086834 // inflection point (13/7)^1/6 +#define PHIS -0.7869823 // energy at s +#define DPHIDS 2.6899009 // gradient at s +#define A3 27.93357 // cubic coefficient +#define SM 1.5475375 // cubic cutoff = s*67/48 + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) /* ---------------------------------------------------------------------- */ @@ -122,9 +122,9 @@ void PairLJCubic::compute(int eflag, int vflag) forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); } else { r = sqrt(rsq); - rmin = sigma[itype][jtype]*rt6two; + rmin = sigma[itype][jtype]*RT6TWO; t = (r - cut_inner[itype][jtype])/rmin; - forcelj = epsilon[itype][jtype]*(-dphids + a3*t*t/2.0)*r/rmin; + forcelj = epsilon[itype][jtype]*(-DPHIDS + A3*t*t/2.0)*r/rmin; } fpair = factor_lj*forcelj*r2inv; @@ -142,7 +142,7 @@ void PairLJCubic::compute(int eflag, int vflag) evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); else evdwl = epsilon[itype][jtype]* - (phis + dphids*t - a3*t*t*t/6.0); + (PHIS + DPHIDS*t - A3*t*t*t/6.0); evdwl *= factor_lj; if (evflag) ev_tally(i,j,nlocal,newton_pair, @@ -216,15 +216,15 @@ void PairLJCubic::coeff(int narg, char **arg) double epsilon_one = force->numeric(arg[2]); double sigma_one = force->numeric(arg[3]); - double rmin = sigma_one*rt6two; + double rmin = sigma_one*RT6TWO; int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { epsilon[i][j] = epsilon_one; sigma[i][j] = sigma_one; - cut_inner[i][j] = rmin*s; - cut[i][j] = rmin*sm; + cut_inner[i][j] = rmin*SS; + cut[i][j] = rmin*SM; setflag[i][j] = 1; count++; } @@ -353,9 +353,9 @@ double PairLJCubic::single(int i, int j, int itype, int jtype, forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); } else { r = sqrt(rsq); - rmin = sigma[itype][jtype]*rt6two; + rmin = sigma[itype][jtype]*RT6TWO; t = (r - cut_inner[itype][jtype])/rmin; - forcelj = epsilon[itype][jtype]*(-dphids + a3*t*t/2.0)*r/rmin; + forcelj = epsilon[itype][jtype]*(-DPHIDS + A3*t*t/2.0)*r/rmin; } fforce = factor_lj*forcelj*r2inv; @@ -363,7 +363,7 @@ double PairLJCubic::single(int i, int j, int itype, int jtype, philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); else philj = epsilon[itype][jtype]* - (phis + dphids*t - a3*t*t*t/6.0); + (PHIS + DPHIDS*t - A3*t*t*t/6.0); return factor_lj*philj; } diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h index f2fab703a6..9ea63fb22a 100644 --- a/src/pair_lj_cubic.h +++ b/src/pair_lj_cubic.h @@ -43,15 +43,6 @@ class PairLJCubic : public Pair { double **epsilon,**sigma; double **lj1,**lj2,**lj3,**lj4; - // LJ quantities scaled by epsilon and rmin = sigma*2^1/6 - - static const double rt6two; // 2^1/6 - static const double s; // inflection point = (13/7)^1/6 - static const double phis; // energy at s - static const double dphids; // gradient at s - static const double a3; // cubic coefficient - static const double sm; // cubic cutoff = s*67/48 - void allocate(); }; From 4f41208c12c0722784845d7e917e299d2a655627 Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 30 Aug 2011 22:36:20 +0000 Subject: [PATCH 081/246] Added reference to Ravelo et al. git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6866 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_lj_cubic.html | 9 ++++++--- doc/pair_lj_cubic.txt | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html index dfef57809d..53451ca6b3 100644 --- a/doc/pair_lj_cubic.html +++ b/doc/pair_lj_cubic.html @@ -43,8 +43,8 @@ the cubic coefficient A3*rmin^3/epsilon = 27.93... is given in the paper by Holian and Ravelo (Holian).

    -

    This potential is commonly used to study the mechanical behavior -of FCC solids, as in the paper by Holian and Ravelo (Holian). +

    This potential is commonly used to study the shock mechanics +of FCC solids, as in Ravelo et al. (Ravelo).

    The following coefficients must be defined for each pair of atom types via the pair_coeff command as in the example @@ -104,6 +104,9 @@ support the inner, middle, outer keywords. -

    (Holian) Holian and Ravelo, Phys Rev B, 51, 11275 (1995). +(Holian) Holian and Ravelo, Phys Rev B, 51, 11275 (1995). + + +

    (Ravelo) Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004).

    diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt index 6e906687e8..561c95232f 100644 --- a/doc/pair_lj_cubic.txt +++ b/doc/pair_lj_cubic.txt @@ -40,8 +40,8 @@ the cubic coefficient A3*rmin^3/epsilon = 27.93... is given in the paper by Holian and Ravelo "(Holian)"_#Holian. -This potential is commonly used to study the mechanical behavior -of FCC solids, as in the paper by Holian and Ravelo "(Holian)"_#Holian. +This potential is commonly used to study the shock mechanics +of FCC solids, as in Ravelo et al. "(Ravelo)"_#Ravelo. The following coefficients must be defined for each pair of atom types via the "pair_coeff"_pair_coeff.html command as in the example @@ -101,3 +101,5 @@ support the {inner}, {middle}, {outer} keywords. :link(Holian) [(Holian)] Holian and Ravelo, Phys Rev B, 51, 11275 (1995). +:link(Ravelo) +[(Ravelo)] Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004). From f9b08962bd25d81b7c7037ebb49d4c25daeef042 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 14:31:11 +0000 Subject: [PATCH 082/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6867 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/Makefile.lammps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps index 3a5cd938dc..3af9620a29 100644 --- a/lib/cuda/Makefile.lammps +++ b/lib/cuda/Makefile.lammps @@ -1,6 +1,6 @@ # Settings that the LAMMPS build will import when this package library is used -CUDA_INSATLL_PATH = /usr/local/cuda +CUDA_INSTALL_PATH = /usr/local/cuda CUDA_USRLIB_CONDITIONAL = user-cuda_SYSINC = -I$(CUDA_INSTALL_PATH)/include From dc6ff70f913ead12add8120d86e0ca5ecae0b480 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 16:04:36 +0000 Subject: [PATCH 083/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6868 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_yukawa.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/pair_yukawa.cpp b/src/pair_yukawa.cpp index f2a92e72f2..85359921db 100644 --- a/src/pair_yukawa.cpp +++ b/src/pair_yukawa.cpp @@ -50,11 +50,11 @@ PairYukawa::~PairYukawa() void PairYukawa::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; - double rsq,r2inv,r,rinv,screening,forceyukawa,factor_coul; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r,rinv,screening,forceyukawa,factor; int *ilist,*jlist,*numneigh,**firstneigh; - ecoul = 0.0; + evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -62,7 +62,7 @@ void PairYukawa::compute(int eflag, int vflag) double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; - double *special_coul = force->special_coul; + double *special_lj = force->special_lj; int newton_pair = force->newton_pair; inum = list->inum; @@ -83,7 +83,7 @@ void PairYukawa::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; - factor_coul = special_coul[sbmask(j)]; + factor = special_lj[sbmask(j)]; j &= NEIGHMASK; delx = xtmp - x[j][0]; @@ -99,7 +99,7 @@ void PairYukawa::compute(int eflag, int vflag) screening = exp(-kappa*r); forceyukawa = a[itype][jtype] * screening * (kappa + rinv); - fpair = factor_coul*forceyukawa * r2inv; + fpair = factor*forceyukawa * r2inv; f[i][0] += delx*fpair; f[i][1] += dely*fpair; @@ -111,12 +111,12 @@ void PairYukawa::compute(int eflag, int vflag) } if (eflag) { - ecoul = a[itype][jtype] * screening * rinv - offset[itype][jtype]; - ecoul *= factor_coul; + evdwl = a[itype][jtype] * screening * rinv - offset[itype][jtype]; + evdwl *= factor; } if (evflag) ev_tally(i,j,nlocal,newton_pair, - 0.0,ecoul,fpair,delx,dely,delz); + evdwl,0.0,fpair,delx,dely,delz); } } } @@ -309,8 +309,8 @@ double PairYukawa::single(int i, int j, int itype, int jtype, double rsq, rinv = 1.0/r; screening = exp(-kappa*r); forceyukawa = a[itype][jtype] * screening * (kappa + rinv); - fforce = factor_coul*forceyukawa * r2inv; + fforce = factor_lj*forceyukawa * r2inv; phi = a[itype][jtype] * screening * rinv - offset[itype][jtype]; - return factor_coul*phi; + return factor_lj*phi; } From 2a3f4729f8215ad5e97f8f7f6b144b2056fca173 Mon Sep 17 00:00:00 2001 From: athomps Date: Wed, 31 Aug 2011 16:10:01 +0000 Subject: [PATCH 084/246] Put constant in a namespace git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6869 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_lj_cubic.cpp | 10 +--------- src/pair_lj_cubic.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp index c58df8f989..545e0ab29b 100644 --- a/src/pair_lj_cubic.cpp +++ b/src/pair_lj_cubic.cpp @@ -30,15 +30,7 @@ #include "error.h" using namespace LAMMPS_NS; - -// LJ quantities scaled by epsilon and rmin = sigma*2^1/6 - -#define RT6TWO 1.1224621 // 2^1/6 -#define SS 1.1086834 // inflection point (13/7)^1/6 -#define PHIS -0.7869823 // energy at s -#define DPHIDS 2.6899009 // gradient at s -#define A3 27.93357 // cubic coefficient -#define SM 1.5475375 // cubic cutoff = s*67/48 +using namespace PairLJCubicConstants; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h index 9ea63fb22a..81caa3126f 100644 --- a/src/pair_lj_cubic.h +++ b/src/pair_lj_cubic.h @@ -46,6 +46,19 @@ class PairLJCubic : public Pair { void allocate(); }; +namespace PairLJCubicConstants { + + // LJ quantities scaled by epsilon and rmin = sigma*2^1/6 + + static const double RT6TWO = 1.1224621; // 2^1/6 + static const double SS = 1.1086834; // inflection point (13/7)^1/6 + static const double PHIS = -0.7869823; // energy at s + static const double DPHIDS = 2.6899009; // gradient at s + static const double A3 = 27.93357; // cubic coefficient + static const double SM = 1.5475375; // cubic cutoff = s*67/48 + +} + } #endif From 665bf3fd1e38261c6ad4d0f5c74b2ff17e51d321 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 16:48:10 +0000 Subject: [PATCH 085/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6870 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SRD/Install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SRD/Install.sh b/src/SRD/Install.sh index a17d81a2c7..27f1302c71 100644 --- a/src/SRD/Install.sh +++ b/src/SRD/Install.sh @@ -1,6 +1,6 @@ # Install/unInstall package files in LAMMPS -if (test $1 == 1) then +if (test $1 = 1) then cp fix_srd.cpp .. cp fix_wall_srd.cpp .. @@ -8,7 +8,7 @@ if (test $1 == 1) then cp fix_srd.h .. cp fix_wall_srd.h .. -elif (test $1 == 0) then +elif (test $1 = 0) then rm -f ../fix_srd.cpp rm -f ../fix_wall_srd.cpp From 6f893a10ac0b5a34b9c49d6ec8b7ab1647b8caa0 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 16:48:42 +0000 Subject: [PATCH 086/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6871 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_modify.html | 2 +- doc/Section_modify.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Section_modify.html b/doc/Section_modify.html index 765f7440ba..8a85bd0c39 100644 --- a/doc/Section_modify.html +++ b/doc/Section_modify.html @@ -22,7 +22,7 @@ with minimal instructions. If you add a new feature to LAMMPS and think it will be of interest to general users, we encourage you to submit it to the developers for inclusion in the released version of LAMMPS. Information about how to do this is provided -below. +below.

    The best way to add a new feature is to find a similar feature in LAMMPS and look at the corresponding source and header files to figure diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt index 933520a04c..662a1729a8 100644 --- a/doc/Section_modify.txt +++ b/doc/Section_modify.txt @@ -19,7 +19,7 @@ with minimal instructions. If you add a new feature to LAMMPS and think it will be of interest to general users, we encourage you to submit it to the developers for inclusion in the released version of LAMMPS. Information about how to do this is provided -"below"_#package. +"below"_#mod_14. The best way to add a new feature is to find a similar feature in LAMMPS and look at the corresponding source and header files to figure From 8be0a31b22afbe05bb400eb9d3d32e1420b177c2 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 17:10:34 +0000 Subject: [PATCH 087/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6873 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index e41eb3ca21..702888b30b 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "27 Aug 2011" +#define LAMMPS_VERSION "31 Aug 2011" From 4fdd629988259199dbc63bc184fb0e9c76bee3a3 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 20:08:31 +0000 Subject: [PATCH 088/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6888 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Manual.pdf | Bin 4476365 -> 4605553 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/Manual.pdf b/doc/Manual.pdf index b7029796d29ed83394c0fafb0221a08f25080154..fba5069280233fce2927d42cd410ae6257c2609e 100644 GIT binary patch delta 1482234 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

    mJD7q}3>g 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�Y~c}oYQ z&x!Q2HB7ycZPrX}LHh%_!UVg=Az8zJF4)k|_7Q6@bVO9j#EEU=%fXa$lY_Dw0TPP~ zN9{Y4KJFDo(E+nVn%IfN?umdvzkr1&N|n>7I5m9CDFQb<2F3|6p6R5NjXO)!{kj1F zKh{n744;iC@P)E?jAA~+LN*1}7Uy(Rh{(eHpO%1Z2)|!%ZIf2U8+t@Yp|u)+iGpQ} zE}5DG!cNv0fl`a+u-AU^#Pp^ON%gdK>}_~OWlM_3i#HmgTWIE0UI^nQlcq!yU)xYf zy$ysNW7JHlK`6=XDcQwI>i9@2qih=tW@d#XW!$)jB1aptxcy4!N2nYICo|}ehC>ZJ zGnISAs}x6KX4ycajKHhbbPCXaddh~Z1hNwNWD*EAPOVt&jxYIOGJ@ifZG|@AHnWNy(2rq-*ZDpvaUYitGJ?5=uCM^@#E4XWpxM7` ztx-0V!jh~!-`PpKYBHC9aKMkuSW>$Jm4pdu7x(cGhS1%-$ncu13=gH4RMSSX9YW6= zfm;s8VPs^aifez=IkJ->hRSdTy{l?hLiQmmfvf~JR{}IF`>p~D77aL6eAFsYZk`%VZG0YwL%)vzBvu5kxsk3xkDfI`5ZR?oCZ;_g zqh>9Ht6-3uar7c=N&;7$vWXYE!z%c&x*^2 ztOT+W_#_g*jcV0@M`dbTn<|D39^5t7^{69{-nv`w52nue-m%A(Rbx?Tde!`vY5)EM zr_EeoJ`fF5hLG~C`2xa}Waa9))3)BGUv8Ofla@1OB+S%&61p}i52XilAx{$X6PXfG z2Bi&r8LY4<_tIfQV;ws0w(H(~dhd9~c^6b9633qK>y>MNi$uMEV4YPWk%1k_+!mNfaVu_tS{fQ-wt<-xDU&M50kfgO}Ad#9sjFS)aqLKvTn)n!Ds#D z?gz1$7(n-bPrUi6RNc|^`BYcq=!Zw0@|)B7P&o(Al9}I6+eqCKr0s!A9+d-Mo?&vn4T-{p7v^t)g9!+cH#`prxkBk*E0 zN2t?5G4i)q!jd2x_aL5S@DiAut@10bRS z5}c=6jZhGi$oTac`BR9pH(3c}C9tUy;IpW;cw8f{x$?B1{)A>6UeIf49WwmddmbLu zj91uFTeD(z-_EhZ@+OQVFr3nj(VQ09L$&@yqOPb!w` z@44^Z4`+UuP-?^IyYISn`1Q0sZHs z`yY9XpKygjVP}etA6kvCxoPkjqyIaeA6hlCFyt=ybwtMf7b?P?u{Yippj_V7ufh5dt zEk7Is2dyovtNFLjD6hFK!9=pC1rW=BnhjYAWF_#aC4l*fH#b+Ge!?#f*>~SX^Ji&_ zl4jbPT(o#;eVk9T)-^R%99$)@rHcG%&?W!`_8LVeR{N5|CoIdu&j`1NnUHsR+#_*suwZ2Etm{mx!{b>C)}QjDDF!F?5enMfqi zTAOSxTd{1`uTJ@8tW(FEN8DRjRw*MF5kuF-&xe^6tzJHT{MDDA^Y9Z7$GZ1F>&m~3 zdg!jLI>hqJ*Me4sc3TQ5)j@bxJ+ ze#93lX{^rg-|xV@Jlv$rLe{^RNwOayX~j-H`pBqjuetilVMDLJ`s(4shhJl1_%+vE zJ^b1$uNpq|iYu#sYwFxcVp;SeVPrlq0>tCRYR8M*t-54u?th-RHx}zVZ6VZ=%KD6K z5y4)%VVaO}t9&+@6J?R5l|>SSU;K`w%`=injpcjpctFW2`$lk2T{EX0zsAgkU&A5G5IpQS`>IPOT7N`kE?#OIOWYyL3*cjytScQ76&b57I&r z2XL=5fLNxsyJ4Z_4CJ)22@5m||h_lxb6@PXBP)%t=#c(BysW z7)%97-J)WP@etXSY0p|1!IOOS?k?SS&#@tYKb{?H^oeFxbNKz|mS6t-fR zPP0g|M&@c_CoRH=cD^>>NRrRyB@jh+QG2y7V~xygw~lQw%^H_qVN$_k~iHJiu$F7jqe}TBL8PPhPmH+*WN!ZDrSg z6+7i?68mhw$C{E_N+hpO+lsAh$Vwn9flnxb)_2}~udw7Om>qDK>Xm zE`z?-WL%ZQHgR+qT`s#^4br8IHYFjuZn-~b09al#fxr<0*K3E<6z65f?Ii!_o6}Ug{&ee6Hs|r%+!T(o zuFjBSYX#`0k$st4kv7Z#0p)jC`n4F!RQ87fgxajRBeWRb2?gc~Ru154v7Mj)84jxB zr}dLADddt0R!%U>&p$hA;28 z_nfwp4&SL?Y)it{&l|v$R`+`#-p|wNe)=EJ`zhj!Ex9$7?r*SDm-G4JqRxM~499-{ zW*#Z6PEc+>UowkU2~-(J;4l|K%zD#HP*EBm_~YA>^xkluHyg83Q*r9N$VeIF z9Jg(~oI?gC9>1n#nvD`_QZ6ca)VyWX(XSQMiLI6CbS$UdydCyddp#2gd(A-6k$<-q zW!xX%_&1Bhv-9dkx9M-%gQq&D&Cd7=8*Nl7jPhd@C2oWn+i-*#aoS$m^oPO&43`Nfs$cRW<>or>l?bY<9CS?%fo8;*1gS{Tt zc|0OGs2`LT4TxtZ)a1?w^ZB!?P8hkv zqO}WS%CK7VI9@{*_r9y};E%HzGy9s5eqoIcW8Dhr>_$;|9GNxl5Ftp~uZAD{VRrQA z+ao{?-zPA3T`JmS%VHBfUE!Z9wf#fVg?@83h2uB_mCGeU2e9vf{NfrWns`0+n0~wc z36+-Sfbcbi!i-uWv7HENbsmLSO?WkrS?e$zd84mYmo@nQk%e6!J#15`)V%$aYlfd6tQ;)%uYqd)23TmRuVg_K#COu+;B?xwfJ`Ru(+>CBva++#Ad*QKN1i1n z=q&wTsTs`Hq6rNaYH(?5l1TxUR#x5y=0+NkACxnMibqL{t@TG}`v+@5ir>?P@lm(- zDN9u+u*46C(z}P4eRR$?-(AMa%M4}XA_e|HQ_%D(G$?_S;i7TSqwUciEm)SYk8hLvXb;;(sX<)K1w>b+T@``$tU)d?wG9}765_UHEYch# zK*6q`doUpdj}VXVjm5qbV#V+u9#%CjvYq910phlEu*T=#Us6G(k}nXk&AiXzPW6$C zYh%rgrmzAiIt(@B(2bV%<5Hc1Gd-_;H@S5g_ivcu$pzm$)|8bRx1x~FOyFGi`Nd5F zz#wguQ!DB)>N4-@5cRme7o>%1p(jBwI$FXWULmdE+3h#}>{JffqKwZ&_pPftfNguc z0J@u`^qOKN@75zmuSrJwf@d_(;u=jn|MBQ={u6a$wKalw8w;DJlTwC?7_Le zD8{^OawiCqzvE@`RuiM7oNa?5rcG_60=U_&A80cmS;PH>)1j`!CXt-PNui)>V$fH^ z)V(pWDV-BvKO-rqrpQZ;*dop*pjxi9md{pFIIX*1w5@Jg&Uq=?&3BPW0zAbBVR$nt z(!-dK_fLyxXv#Fr!*SgQsOfqnb~LDo_g0W|WE%~eUoQJ-wuWJ{X+QTcP$Jp@>n2D) zmleh0>JI*u8m*Z7)-;5?^-S6lBnHJyNLV`da}02&P*aas{X85=@865)Tlg}zx!OBE ztwAP78{!Acmk^H-5wD4tfq*WPt$)*}(Q>c7vl$N#wrP5s+?skocOD}k(yR`z5?RbJrK=mu&{N=^ymOh2$7)L zd)nV(VZ3Q;Q-WI3t%ZvrU9mOGMn@2-H3~ zR!*VFpQxvEr0$f(1dU$V2-v;f*J;`%EqQ%NzC-&0XC}n@mb_M^bA}VZruPY1j$om8 zfiyz&!)=KSW7eFS>%Q15goBDbDcg%89%=As2|d#k%( z4dm8^1$1Bzw&(|Uh6^NEo5Bs%MJF5Q5kb}K$P&LXCnk}*TZx=P@Wn=PT}$Q;io&ib zp@(Z6wu!iqY&dvsyy0vC75twgFCTI=7$~w}HMK|v&af78`)J8^Wq2Oj#+_OvKgn3~ z%cYuZr;Sl$vE33_{sW}AkruG2gbz175B#Q?)D`iD4zen6XR~uSwN- zPqR_gO3}lQtAQ<58yCt}feL3rRmi-XpeMD?+Y6tkZF;+Q-x&+|W-e!D16+!cusF|g z+QXg*TX!G*gRn*#fs(o|DM1)MSP4BOcb2P69XBC0IdhxGWTb^wc3EL}a90j;AQ61C zJS4)BG&bn_R<4Hvsv1}nS+MgX8$W0?M*a6gLgL?KZLq56U(}B3TJ_|HO_A(*-zsvo zMW2HsD*Qo712b3wOg0QQj-H?*%zx3KSj2K`LS|+H!zM@PS55yQPAgIIZ^HUAXdY_@ zJ%J2SzUxJ*<4xi1F~$5AhDmg;T%LK^{>FRp8p59_N}%KeDB2o~d@}MMV>YIQD~+}! zkWNjd@{x<2uq1B(va~#z6JtUj#QRdennhO!i6EACbOCk9CDj}Fpax=psm2QOcmjkNckcx9-y}HQnnWaQ$wq4#%n;JUtJ4YCrX}|fOUWdR zCAJ!q?{=Za{~%(;I*QP>!II`k;IA>yjDJ~wbvG}IHCbLVzfWT5)BQH4@_F_MA}-Zd z{3qj*H4!WVFouDnbIcQgv5{R@*pdd)3E7ev%Y7Zn*krzO;-k@%T1tL0hDxi|o~cpJ zJgjWg-%yQf=t`jnkcUh92%Dx?*1B-4(SE38RiYYwRL|sehOHhxZxs(cZXVK9Y#rZj zJ%Exd#y;aAUzw7UaE4er;OD*@>SS^kOD3Suj#{w*$}%Ch`w2Nh11tMvlA(<>nAu)$ z(bZU9*PKAdT>{JG^TtUx=bmdff#XUxxm>E?WpBIMSL}Y_hCfk>6y>TwUGZ0GpMY}J zBsK;UG?^W#G6#5tj6?PMH>XNqVP6p(ASZG3V)xjl(%dorYG`c1gmlt%F+K;4(HCLNT4+~AUik}fVQxU@%*OM8>$%8N=8#jE#b{Lwun`1n zO{NA5`AvgKY@?b;uFLT@O0;3PX16A@HPRyy#L;?9j*fRuX;9ceY9aYGTm8md>=x zzNg=IJgsEz4!gKV0_7}XZ9(7nK?52%gRn`Pkv~x>ebn{pGOI9>6@+BIwiqe;Gr;X~ zY5zjTVL+^lPgoT!TNf;sZ3c}v-mr2iqQD)0rl6AzQ~yu7 z1-tw?J+p|ySfh(krHbjI=5BHE4GE*V`=sch206ml9Nu6GajU3u)h@gG@F)R@a^D%a z&~nynaG{&f6+@wQz8E>Xr^PaVz$dT@vivdLN5 z{qZN<$9}l^zRuU4OcSSk>gC;H?e3V@P89j0DY2vzzAg!3CRksko}4p!;%lJ%bR+c_ zC;8c^MQanH!(cfgqcNt0PM-iEi7$c5ixj+JU$7*87NJ|xvZCga+B8%vCfdvR;Dz>? zCepaeHv4edgLf7FcUpMM?Htm{<&X!oYZZwFGps}0;7zY z-q^{W`gkP#{5a}#)$X(2&kZJQY*O#`_B%kUQx?ab&Vw?rpd}{LF)cfWqn>pLibgZ~ zTMKCl5f39Vbt&wZia3aeOyo)}7eIlJELdbDgiYV|yCFG~nns{-cF9|o>}S@4%#XyU z?{;8&qnY#^VGUTaCkZkD6`4TwSmU0gk@S`yt6?Snhci=y^tc-|EHyLpVm2G$iTJywWM)X(cr@Y$H1MwOTi(kV*nfkC z5$k5@!Cr=LzX+AY2VG_pVuoOXB@vRtK%YgJ9}SBG>GO2T&Tw|ozu#@z9FaxUw-dd- zaA}~V6H`gqM1_n(n7DGvBcA9*8d;RD)WIf3mhGs)Ey&y(In4Wm?(}3b@{Q2b;bFJ% z7E@NE(|)%aa8XVMDqp;R)+2E!E@x7?<#@Cn6@Uedco3(fvS)yVD>2v9qDa*4+gVWY zIg8ZX)dtDahS(gStIEb@6&6BBaF}|@*A%I$KusCXL`&d^bv+hSM?UVAYC4Ev83&XAM}F%pNjT}J|m2T zxxLCvFruFli8^tCAjO-C%F$w`Y*2~xB2|5=B>mL6^eb^3*NH%X)2f4@pSN^LA@z!4 zjCJX%O>|$^V}8BR?e)6;j&CEoPqFr*Bv!y;1gV;pUl^vSDQTo!jGM*z)D`mYam|-GfI)#sw1AQ(ScW(+|>>s&~>{l+J%2%>hJ3`FMz{3;^9Mx%;?p>1sSW&|F`pYyC_R+g412hSr5 z0PN#h*Q1JS#O{!~Mlr}Lb<|SUJ(Iy6wCutk?R2<)dzeCz0$b8kY`Q_>e5`7zVMZnx zAcnLxpB0s@HDL|0B0Vd@gCrE9iW%RdueLC^wqpBwh@jPTf7s#{BW!yx0o}3>0pxJF zb>!&=MF&qJ0R@sEHCWlXY<1N#&Y6<~(DQis3yyFEJ79?jo!giu=kN1b69343{OxIz zST_n)FCfo$01aahKEKP^LfLZ$3^o#0gc@4kjtx1TdI?MRfUzxSDlM1bA72|-1(vpG z!x&Yr$T$fttl}`Gk_bdqsD%{YZNJkobrK%2#Nt#Mx29q%QIIHae-IvAxA-X^pg+%p z;tnb8OPfXodd8m6ktawj!i;;RK zxD--HX1vKIxax<*7zw&Thf7-M0B`vHADEln+Xt}JoibYzdyKbBX(8fVE(U_dV9jQTuiI*TW$ueGB_lwxSOK z=rU@^B@3^h4)R@k@-trm#z9QNNCJI1wUua7h!)iDA;kE|e8rY&)BDO7!BBKsII8ge zu%w2P#0%B?pnd09lv-LxDs@C6Gn@9jF#G(tLE!yH%x4Hvt7n2zFb_(A#4aXBr4Wf_ z$<66*I1x$e-Dw|YZJZA#n8UJ5wt1U^42yWCE3($+K=^9i`2D&FNKsCLAjUrB53nB_ zklx12>#sE-Qj=hrQ1k$~=GnpSGS9u%KZ5U6q@00qrW`w7CWe_+8~ApqjO_=1z!h?% z`4IvpO-Al4a`FY@kxpTex&6MoYt^M%J#0^z+TrMa(x>STq--8k1`9u-!_o=IJUGzx z7|CAukwS}bMT?LG{wWEM*r@4rd5I?C1S!YpRo10hPMw&I;||BRQO|n)mE?%BI2reD-iP*f;C>nG)vFCx^3|krZ#CTV=JfmdF{E=l=N3 zl(&c=x2yRsfTrXWXr966b1NTCaj32eY%AD$}0V^0(NL zQzh42Jbu&$+7}+L^it*V>_qRFu$~F8 zfQZxuq*CDHuqiDK+!Z?{@LvF{VJ0HalU8lio25qbrq0WkMv7+H%uCw9L}WW$bQxGU zOtQF?JFC5SNqj>q!oJ!r4uu-w&v_&cVeF2T7`Uy*Ai`ooH|&X4&pWh`lyU|sPBohq zTo`=h)R}dztXz0pcbfW6kr~Fc^XM{wJl8Z4nv1Ec+R*l)*8P)PbNu_k*Tjva{6|*9 zMlx0x)WNk_UcaGO5KEt@R3OE9H3L91+5WF?%rLY4{3X$!`|;T6W1D}0V-eqTJ$kW% z4kVj!For1)>>o4_4tKf_aqMggdB7)wB?LZ4^o+D0h`0N7%R)MbXIQWr|RXB+3#3K2z9EaPTZf5wl}Kn4S_VtcJbk z=1Ej6Bs8sHU+=&CkH4=qcU2;b?2-n?WI5bNneQ2AzW<8G*n3im0Q-La1vU>>u`SnP{ME^I=rW%kGmqEl$cRu6K zCt?ynCL7i&oG8zgw9xURnyCw6M-R6lqM4-7E0`zEQrZs%KG1*MXwph4#+6KLbbVgj zs+IiCV6-ld-5w+q;>-hqiLTjoV;&C+yTFeVk4P+{hctkOI1z9;EFi?lt!7fjfm5R0 z5D*?%a>f7o(AjF9ww<2-dA|%ReT1RVN%3~~7%6k}xc;?}15+;WJ+wrwf$h58#r9Ox zf3)cLcj18VfTHWM=Zy3eKi*lx!gjeW9d&i%xO2XEbcFM9?GUKADm%1>5nf)xK!k9K z4ABz=C@mVzpW}1m!JcaUWljx{Ug!r3s&W|7AZ`7yz64*lzQKiid5*ANR$|#93m9T8 z7{|Ikus|&f>NKp$BL1YMzyIhRK_kiiL8IPD(XuoKfcZ2wJS&B$#S(VKw-rY9eawgc zER-M=`2V7OAX3fMVOHoWg@g1wr~2|!c1*Xj97 zSNpGAnxX6*)Q%GL-!T}nDt`(o7MuH+iio#gtK1S%BbQ8=S)#YieRfcK3p*o$l~B8qa_@hhnRb3QYo@Enu_Aw zeg)o}BQxnnWP6hbf{`IlaLM}vrjp~W>{ulUmFQbu3a!T{;+HQoBgIVZxNmCzVER<8 zRP(Y(GXCu{xf}*C!Yk5ILJsjxtkAXA;W7yp@TA$(l8`C7=c->Lm@6H0gxa~RxEwh) zjxGK%8S`*CdmMx%w99DZ_Me@C+ABc;P7I=?Knp6 zeo~Ou*py~=()};@)$ZRk)1cfqOQ*iDXIT;TiYhQ(OOfIDLfCV;6-p65BkePa;zzwS zicyAZ#BG6vD`)DUz&sHAvM133kz* zi06km{{WaeemawZ&`1RWpps~U)HBJAzA`&Ky?vi3n;3iN9@oG#Y-|pB4-ox;_YQa{ zFp9!upMQ!ATO);?Z z@PwKJt+MaBCc_XE^@NIG53S229FCRu8mfCNGiR5=CL%j1cYEGlhUh+WT!+jK_!|lcTs} z8BmG-bg*q?FAL=(TD;V%f_kX9cw?sn-cx^>$9UXVI=m2fzowqaEs1>D0g z2)ym=8er-;=T}e*&8(En1a@>74I65V<>-9{O{d}bO3+QKFZ{$Bph`9-QWSFWKr7g; z9C&3rN)DYP?@EGjq}7laP;%}IS3HvP`B|-onL5;Zs zLr#;g9*0KwGRkFWjs*LIWHCYL5J-oxF4!l3ai7QkJ8|!M-no{s!h)=;C2ZrMt1y$c z+k5aV?)|!)7}$s+7^%A0D30$vq7aeQC4JKWKj{Ep7fMeb$l2 zv5=NVjkxUD9cr}6lA4m2pbE$5G=0vop{S$7x%(0O>V1BNsfQ~LPp);%yhy9{*7FxU zn!30)HHYty!>!58r>w3zV(kuhk{9hJ*2bmEP;X&+Ma*~_Cu}+6_Z3sLP8>{ zY^@Z0QiTqCyVg>sGE1Ns7J1kv0I`Rr@V?jqu6UPx7X@IOAzP{?qNLmV*24xIIrmmpG{kJzv^SGsqr1 zoXuQf5O<3AV0<=_Y@02=py(eM)2X>mn7x%G8PkEp#7=%&EE@MB^mc5tZJGU-sITsK zPgrKtYEwbi425Fc#Fs|V?eekvV?w%GM!T_TH`+}1DHE{6Z>=loS4_+%|Hf}9^V%aY zN>ALsTZENg*s285U*8(ifR8bWF`n`JG?d~Cq6)}hL-(I-J+A5dG!x~c&lRcsVR|r= zdQi}A*>-xv|8CQ7({$nMXH!N?hwXA5LtlH*XNRMpZlf6Z9AdECef`%PxgWNF$zZbsAlQ!>Duk+lvv?$;g*ibyptfMSnUU^jeg; zUO|rUtAvVC3k-HZbi4Oh6-Q=o#!FU7HYxKzFAqC?O$%l-600M#pZxcH*q`cX%CvUx zT0;6x>5tWw(K4`D9%yUR3oApH-ru*PnS?(R-vNX)R%Zj7@WBXqLNhJY1el*po`>xe zZ@W*md%85kT8@Vr-JdT8{Mt!hJNe1=&>@{)<0Wlc1!VZ&qa&?zWG;XvMUc&}eXjM#~~1MJK=Qzm)HLL!I}FTK}2E1a{Os*ge5?QTZLP zi}Eh7>S8*rCL2Lhy|~K(?tfdlucyboxXA4NkwBBGT=)Tcu&0MGMErD`=(M%*ip#$b zY3DEjp=0#cLill9$z=EYbhcG`>b#g<6a8#{ZU$w=Z1|4U%#^E4Y6;>Kd?h4Q z&e)`eDQ^y>%ItP^U2#UG@Ep1-Lj9px5eGAKsPZ^ly;ke`5P9mV6yjq?l4gwor;{n4 zw?2-ow;ziR$&;NAshr*zWBkeM_PD0v5-Q}lwy4B14MJ>Qf{cYJkwI8-5!A9xi+YQA z3~$#n{3(nsnzZctXEqOM+^+29Qb5NCf_)f)UFINXkes;m*q5XGK3MNl*1Al6yfcl? zg2()q$PSF)_f`uV(Ik_R!$dhCy6d3Zh{7-R{TE1^4pDMJ?x)-2x2cD)fhxl5M-&H! zUvK$Bd1+#im_z&VNkgO@*^^}1x1{zoIvnY!!^X2UQef^*U-A(Yz*pKB=O0pvaIYE`ql-J5Af219%zFcaDjdhnzWj@5=Zl8A1~7~q z&}C((!$D0Y#*}oDRyqWL#xv1eyWV=zo1}{Ov_#mb_Df}X*+E+kh7o6z2%q@uiO5q! zS-t5MEmGI?(2(DqO{-P^e^H=u+;prOv+9{!-CKU{?hm-%2}Rqf=e;HV?dL~Fv^}Ji zSL3nYot9S<@OeG4VFc+pZ7lRvcixok2m{qEb!|nHk)$fVNkx!Wj_h=T?Ivm3N{baE znS4%z>(95Q<7s@(s|73dW|Qg7`l}7tEX8LjY@Qbx?oLaGRfYEpJ)vv%`ab>lrarxTjpM0R=yu@MBK+DNw5a>?2u$D$9d5|t8%9(Z@6mdL6Zs^ zpwdhglGnRlszfoB#sS>iVY3v;0hzp3gLfw^#WLBPCWGUxw-~=NBfg5G%uan7*(|06 zFUR@rZkO#?he$Pt2I`|wON@SV$A&-bZxqOz_{>i!LV|g<+j7n#e3uu)J><#ku0}(i~${Zcv!(W+C z>{kLYlxV_Q5GA{GV>Y2}PGrK{WBg8|+7Vbb8$p6d4@xbz?}+N=M1{QzGs}EVii+ag zFziQyWPLx(B!k{-$y{|@0Mn7W$FKjwcq(6RM4Ei5O5=JT+?ADmFS@6&JLhxt*4LlU%@wK(Afbw}(G+`SBtkZE z)vjuJ2qPOi+W37Rb4lpI2#Z(llpN`H<(HPk9@&UQie2efus?4L*ikyf^aUYcGY9D42?ryz?}pI?!_Dl)5G8kg3`&o%do`&{ zMG`o?<=`@j*YuTE)a4X4?S8CXyk-kW9|jYc|1AQyo?=G_!1*hy+AO0pUv@oRO)+JP zW$(H(xt#UmvT>o~>3GDW_LKVED!Gf>h7Sw@ny>dUU}qHbZkKBEiMckR!9ony`e=*hQKjsYzH z!gi7oTW{*d=(}%jq^r9uk7J}6J|DZY*tj$B-iNp3p3kvkDl6G#BCluPj8|@6?b<(l zKRH8fo`u$n7((^m$b3|+bdND5m-LbkYUh#a6_8BFR$W=An=0jG(q6ALy4t z1>hW5qe@az?L$+gAq%u8EJhYIx2gjg8XAhqUhG_>cut4&anjy4KudYS?o7>@ zZOv^cpH5xyJq8U?i^mt|VIbpme%ugo=7=K)DV?*gv{?`QD>@A0by>M5jOHB)`0}od z{!x7q`}~`!@~z)xkfnF=)sC zC-G)F-Dd?WUG<_w` zX8>>KQNTvG(<%%uhNUKhhIIY=D8aXl_vB#T`i+p$)2I6lxchl)e7Xwi(P~P1N;;~t zk`hWPdRp4?FOM^QRfTq}Rv6!zxbgm>ActIIW$3B@!`sU_M}$ZuYdN{&j~vn!WxkxP zp7JG$&fW}=)AhE)NKC>r*Q@I%#Fn$;goLT6ZJ-$?{{sgK*OK}s90q3QHg5J$+30M% zk5}((YPc1RrBpZ#_1Iou;8U*{Z=fX_jG%Rc>2~3%!k+}UNd#YOpSy%@?$>JbKdYI?eI$|(j~ zN`RhDNa|n!G5{*AIZXJc1ALgpc4(g6#mr;c8UgbL%cl&9`KTpM%U)FZSlAUc?m|+J%EmdcZuZAC2Pw*!!xj>;Rt^ZY}E5GQv)_DM1WSxjB zsfex7p#1jOTHJK930(3b0+0SDvx0Mar-Y=Y&#cw@H^CO=e~N)|sn( zC2X~hIZpVMmRHlCE;%jrsw~9500Zt6NBeWK{Cn%+Hu@$)Gt=N7Gch-BDzIF?SDaO{ z20@Zcj3Oi`{9PIwBU)Z3>!)7&w!`UpT&Gu#GCe2Vk1}09o{zFUHzEBec|XSmkFtFh zb8b$#D$&y0JaA_!C!mR}FX&{*z>IV|cE0`L^vuHxa;j;V_%5@ROMBPR3b1T?=6`bd zq)Lm@u-xk^=ysH;W$RFMuw)xxIE+(@vBSug`b?tX9*g@2j4qR5@G4mCA;Ebd*fi9~ z)x{-xdz|w+>?-C9Qd@o)NLmT6{KZG0?ZIK5naIdNVlwF3z09}e-N!rjQ}482QrNizO^UeYQ|!y@ol`B2PtloJv$ z1^v-@79^ozf1j94!<+Yy?k;N=QY7mcWnSFzzmYjvy#4L+tQcoV03HojW_WSVhbg|u z8wMXZN%$L!2!yc(p~%`(KeN>75HYu$;?NI#f>hb@*QJuRY;Pyx`sv}t5Dvp%L`YcZ ze0z};sqt_250(>JTtsP(c37{I33^!`UDb{Xr12yITCUc{&yvPUWrWz*gr3r3#oh1> z%kO>rEy;Q-K4%1XKrfoOHw+kTyaauk=JMBUs3CjSSg33ZD?)+x-u6TPZP};u_3n7t zWPPl<@hS-!YT6Qyr_0M!lz7Y$=gYhK=;OL;sK1|}h0X*^RaPjrI!dgfC~0G*HqQC# z%0B?xy~oguk+4)pM@Y3(H!D4QMJ(we7NY)uLhJoG@r6(TD@Hc?3ExPlm^jEZ!@}ga zPD=p38}rMoP7GT09G*kv!aE^zX7H&qF%xpT*4M>Y*UimxtL8s{h}F$X%b65j!%=-4 zS7LGvRR?Ct7S6ftvt5T|{RGHMQadcn%T8GA<=CTR2Q;xGWpNJ+{6gbYV2fPWO|uPk zM{C4t9cFESTR6x5xRjpQ7_Vu%9qJb43hj{v!i5aUJUSBH~z|0ABrwmk^D5{RNke7uD-N1l!nE6j<`8ty-nzb)gAtoF!HS zRcQ^N5=B+=duDUb_h^x{pa2ijO#Ma~;sZzhE=@DJjOAjjB{mZ_EXiRK8Ic>kjGrY_ z7thZJPk4*dfk^AFd{5hjO9&h~Dyhcu2glT~cCZG!zaru%;qe35LH7CHo3*kCUv*21 zmLuGx$?_wGTiNSmj`sq~Z7o zjmr3xD7R}9w?)5r4@3H}efgjMnyU`w9agU&?& z4CUvu77MvzWBpAk%+O_{Q?1u+XGZvK+0HZarmK>mAiRtlLCTIb8@~?@{AGDw`uQ;w zBBTmoQe-T-YCboWhI|Bqv~1hl2g1q+?NipY-=hE%kJ#2dvwok%?%h-|pjjYTHX+{Ej) z<-NuE#`uPA&s9wgOW4qIfxC9DkfIl^sIW&4zp_yM4_HpOn*d3<1Y1ebVnw3lgqZmO zR{EWu*({Wc943pveT)W`f<&vPz>f}bU9(c9v43om;J0dp@X_sL_th$3RlQ-FZW9FG z4uhBk&Z9tqjo#pA)xQK4$4)SC+)sWik{BXKP_reNPv|3ZpUbzj&M1N;N1qnk>>d3T zc+KN};FKRl&AeJfH%~wwkNL+#R?0h zG3hZRwvOra9A(3Lx~{AD$5)s09#3r)+Ty07va}|yH{219o)$o^W}O9D;lKBUvWtvg ztcm5T=+K2K9dapwY3ybQ-k{At9q94yWY2!VSsn)~M;QK)*Z5A@R z&LcH6)mW3i!fZ~ftfSOam+W#NZNP8`nOP})d9WlOWLe29({?Kzk*BSXVSlT#gmdd3 zy^oEVL<81;{ccy}Tl5vSDqql+h70EYmR9Jqfte23neEKXR3zGBC;KD*WCSKOQ6-c& z`f+uXs|evT8+P?iW`Z5cl4(;2&gRWjbbH(QiTZHo_K~Rx8CtL9j&$w&Y@Vx5CnUZI zECJ{D-Tg0D!(7DBp0l$X+pyriBCAh@rj?H27LWx_J$ko_ORkKst#w`odF%0et1+!s z772vgPhOOI6D-+&SRgL8CkJdfP3psEN=B~xi5wNOKV7Avz&;P8j!{N)Ok6%pdT}y~ z#e1hWP-TG@3G((SwI)Mj|K%}_9IbdHjMEpIZLw`8_yEsrObM_h~*jAY;|4-V!v=X(rvZn4|%|2fy_a+u5PicMzoZ;6g_ zve~c6TV%^+1RMtAN}hv3!~Q`MU?2r00(dR*o9z!>P!hkw9M_x}PT1(rMxKJQc4}$h% zBM7{%UEAvhdt2%Ly?Za@dn*1uP7fvBe4$1lrGnWbl&-ywW?2#8KR~T03Im%y#ba`- zz>7!ipm`+eqGH=tWV+6f88&T#vohN+Rn>DjY(y%_$#MznCs8akR>}@)v%u9C$$}%; zms413Vk8kBtFF#OY)A7s0FI%*yoEIu&L@9b)pWd8eEHrdx$TDgAI(xjQqHZP_AUWn z3S2JV!o#fpSn@g@B@|`=bdMXM?q0d=nSCO00v%Fx!C}q}f>>wdi_usj_k8^jU|Gb? zXh@W~C1Q!OIjn^DNgR5Sr{`ilp@SmI!qw4xzf2J{gS%KQJyKBvbej!LqIUDtW*JrK z#kh;n1ny1p1kwdCJ#_aExxK7&>0}A>i*^RuXu2I<8ZE&U&n8P8fB>E~nbClRyWV z8qCNF>9TGy?HWozDV~x>t1HLz^24fJo*AV!f!tC30g+~UHpQ!iZq4Wj^wyNYP+`ob zLV68$v)AlMx<6I(#CnnJC=u9N>pb(F6+#)sVDQ2vdA>;yEkkk3aTsCPfpRUl$&TLq z9Ao+PjYZoN374c+cFktRx{2ZRmQ#W^6=8?JT;SoFlj{UNr!_eq{hM7+>!o=az%|f+ zh*cCm4;FQu$s577<6;l)VW4tibOBHe*+4<}maOR}DnH7nLbls=hsEl3V;TFKbx(Cp*}cOLkb`i#aS(4)d|Du{dk z28-p8+JB&vPhv1LQN*c%9tZdcpyR}+I8!x|fCOcr6uw0aQO$?>!_9D_?8QQi9KRp)j0%dX4Zk2E( zbE8;!ehX7ULXSzJWKPhCX1a}>s;oJmYsQqjBR<5nl4^)1{_4!-TD+gM7H*?cz$c4~wq%Un%uNzy*f^ zU8_#fS?Dfp>TuL};_uu^GbaVxh2OhmPy4hOM+za_8O!RXs4~vBeCNVJ`29Q~RghQU zSVR<|Dd2)Wek2R$`v;kx6RT-(&ECO+))RZc-T@p1=F%G>1elm=UZ!3&mO?j6$ZQ4} z)b6oboh|o*SL0~W+ZFAB-aI2g)Gfb(#>9GKXoy--|9&{4mKL$dRmhiW74j3@`R$V> z4j;zDK+g|H(DYQjRMzZ7rPWYo&dM@sYg*@#i=rSmd{~Ymsy|Hs+E&(MQjvSpbPl}O zQM9Y%%+qW{i+EDyOTZGI4L*l4=dla)3w^v4z$$3V)U=1!q(O@VEhSEkw?imylC}@z4BFHdlL4df4;5|@Lwqe;`Bcp8P zG!NoGt~EkcbMY0a2HTNTjIspc&388HdVczmQELs#1UeX*-24!ob*0N03S|Xp_CvAt zyMlC|qEKmVJ|vNfF&HUY_ff8M{}UnsX)L%vq<~HM!axOqM~VW-FKG%~^F6N2 zwP>zvGjMBWF>Ku7KvE`rCdFN#3HjOdyT&7c5rF~uc~3=AgBqLbXBsN19`NziNIRY; zb9uOTt+1ZKiabX1n}sI&3J_C{ikHa^kTJ{-fLwx`qT0ZqJ5Bo^q`hTel}GbF+}Meb z5IHA$;t3AnxZo~Lk>C~*+#wW-LlWFIWGNcFK=DFwDel2N1SnA4DYVG{n%Vn6`}{t< zAKov7?5ywXHP_D0-uX~-_4^^ie|xy=`x@y_BK`l_c4+d-#&0(^sbY1~rB`;ZSEy;m zh*n41`7E#nPu|_`rtR+;#Ue-i>2xVPxa>#Wr4D}`Dzd5a)>$n(m5Zs=XjbH$Q*TP_ z$@r&3iR-T4t;{waT>0!+@K2@gB+ibj+P%-T6DE&I$t5;r^=eUB1dg_U*R$k{$weP; zwx4U8F=VptS9Q-A4 zT1fHSiS_5rnl-rW$fco^o0M$Yt^A~Fxz34cwfbaUIy>>eb!(mG?=or}8k+z1%+H;+ z?+LBgw)(?1f4>Y~)+68R!s|6T_nW>6oS#L|Hr^T&5Fa?iBi!ZnuRliRD>{-PpFS}o6`Fz9n{ExZe{l+&R=e5Fb z&Wv51;_JQc^ti6h*ToC>DkmrX^mOQLAK&)z-M-s8??k!!_uRgF(0JL7AxE$3vL;@8 zQZRb(*74;Y#uras`D=6My{6Fb%sySWdRk{cdK(ZpDWrPiDeW)qRxKNQGyS=7XJ_@a zkoe>|PwTI|wEFjpiS;YoD;>Jv;I)sl&$n;=wsqSQx4%2Qf5^rgg-dD|zkg&eGAp%C z*9HT2Cg>MExjJvcgP-n9@vj>YW*WV5aQNfV{$fs2y_iPhqmM;)@^)K)q5oT_jF~gz z`y_Y&H8LqOxZxwe^R6yG_pLJX;?&j0yc)Qq_g=g+)w5ow-5$>y#i`@FZTo%t+?Edu zKiOL9{K!rt>(*})*W2FJPwO0;=bwAFb>4p0*7slTX}T}klJF-#wkSGWwln?7Og?nV9n>ZQ`Qy|MabB{9|5)n2F`*28?U9Dct*f z#iUXtuGp8Rm#x(=X?xCmXI+ifbF8J#Hd!!oZGOdCZ!R^jG~`UhGrKBe{`AAvy<0EM zes}A3!2#cYewyNQ>B8x2SAOppvGR542u~*f)^0|hV zg@gATnm2lI{%_wEsC?J>Klc(!NfyGL6OC?*J&ug)= z*N9=)4q0#fopWO5h|yYetqC==>o$3qUvt^(An((YA1>NmxYmCEam`jImd(p4^qpb& z_?gvXmihM?H>LcNChb3F&ztP$b!z;FHhmUc@Coj=%xyv6e5-fv%PRw3dH4ndT+8@$ zA>v-C{KTuaCH3k$O>0;p%{=A%ZaZfOE-#mUGWcD%|MPs&ZPLY=N3=taHrTDJ&^_(W zuvt%j*UUR-S~sBM(Pjy&CbUm9M9uEeHgnCeu6tX&+0n7)vxMutcV6FLx%lY6X%(6(`o&z9(MAK!1T`>MmfCM_?~br`&9S;n*m_sg7Ed%X3lclcKJjy~lF zJX-S6Q0AYzQ-`*lU1V3o#G3PlPXBq?A7z4Sl&RU>P^YH4#)OEO3nvd4bj~fqJ8o6T z1N+^c=kGUi_jDT6;N0ur%C?mQ3eVlV-88HDe*c=gUXR`sbL`~%@9w-<^d!A!@h6&J z%;iIG|LyHHzG1Ipr8<_ox?;pST?waF``g!OmDT9b_|0_|R_HSRTI0al(Mt=bUuo2( zY?7&~uG7aVWt*3=Z@9j9*%wR2gzeAzl)kj@?y?f<4#``0-g$PUZikO|R1>eNuBd&WScA<53P&LzWzh|A2bgU zoIR=Y)aMs=|MO}|_gFvwQNqeg>u?Z-3DCD$%$HlW6L7v`NC+a>+R zh8f<`BVIlVdOhQGdQgoKy=}2YPyRZ**7A|YxaiQS4bRd8KO;)j?1kGnZP#TBE03x)ZNo0@$TJxqf9-9oqw7BEk0}vj zuh$DaWG^-JUHKPp_FLQh^FZ4^x!ioqo3MPsZbkF^+S*y6gA4C1JagKxCIcR?4nOV}QgT<-PaaEcKlN6p*SqX(pHz15 z+gm@07Dt{9{PI>`cYJ&|OC|fkWrsBWTRyz;IC0-?X?E$h*>ATm4qkd_)y*--)#18> zRaO@rR%55f+oQz~$Jt8_i+nS*?xLqx?>$fc_@&45p4r#Owu}Dw`T3=`<<7UBR`E^X zkjJ@&GP1(Eyy{Z^;mIF6`m3s@Zj9}AwNZN3^&xv^TQ{t&Zk!Y!7U4H-RcKGQXK&g?O{$nNyzZA!;IPMftWyHdqV4aVGhI=KFp&qE@5B`?cM*;MC#=d$(76nWfq z-p)BkW>0PMSILR>`j&P{9djXe`%BX-w^bjS^myz)bV&BfcLSV8*th3BujDIwPj-#m z(X(#Lzv7qldOY~`!arABs~mK8c%@~>@j1@0cMAvl+@I9^{^$jdR{#3&*1`0Hi<)J% zjNhKTwt3Cgr+#b{@iJrhdiw?U`_F4SzbqUQelyzjT(Il*5|ceoPjQ?3BLBmZ$R0)J zZ93m6vF)B(=Vwi=UN^nipnf;J?Dfk${-MF^=8Z$fT-iD2bG2CAq(2^h*>UamjogYm zwU@QGJ46;ewzp?N{>!~>!u{v%Xj-><$yIOMd#1;ZT2!o9rI~5345t^Ieq6BY%=hDe zaGu@r(VyDv^I3tv-`;h$&%^EBqG9%-i?Vr6t5xg{!=nlxs>s^Y~eu8k`G z=GloV7g{BF=lge=k@d>;w#)6vvs*THk9|`owphK^wXU@_nZ{IXX)6C`tomGq23_9V zX}z|yi|>*<>)b-T(jS)I)#Fu};1E-#9_?40{M72v!QFR17IPXQ8qduaQP#}u0Z)eI z&mYzD$}wxVclV3hYgAdkBC>+dwY#f34lW*6zILY}TT1`4G&*ryhn2;Ds-4x*YvrVa z7iSjt4*Rb3?0ap`WEIryZ5lfGtZ~4Nx@&j+G39cHpt{ALZE$Pdu;SbA8vQakJ*8XF z`+(`wIxM}mVg0G>LA@XJ@0-+UbIgecqb9XmKj%zAiMR(D4==2_+;61eQJ?Ve*+>;B7nlyjti{vElUL)qa_fbD+bGJ;v;}>5CG5k5BciRqE*t7o$g)F>M}N zU7}jLrfnQscGInL&zAR`Ztk~o($h)(->tY-{dDs3?ai`3B~8B_-7;!e*P_nj8h=h* z(L1i=jYngDC>XSML#eK%2W`rF*;CbQ$IxdLi)y=!QO&EA=j5zgJonfYk1?tX*RnpV zZY1vzbFY0UIFcW?t6X~bFMl>lE%wMbsBmbz!AFPuoxJ`~t@G#FEh}*yU(XxUzC!)s zH*YpA^SMXMD}RUuH}B;AQR-RgnLY)pbIY#KJQ@4js?bx1hn(wqpi^4In8^Gxlm79l zWNL7?T=}K;C1F?Bj#<-Wt0`vXu;!>$`iEUf?A+k`Kus6Zh#k$E#{W9(aeA-v zONI|=(eK0OZo77Nw`{HTHmE|e>(A0_>g26A+RN7I)U8X`{?TT!H^wPkoEcRiF#T!s#GXx>hAeE6&=et?+_Xui#<`DN?7-l{xRnPf!)#Iwk(_>}rYEA7*X!k8)BwcaLv) z&}~Bek_xqAvNFn@FaKBHXZA(6(mR)X+JD6lbtiT>`Ek|_`}%(tJ^%9gh&}k1x>GX4 zT+FJ^t-VKQ_y&F#dMCY6)59x$K7w&e*$p{Gq(+wJN->f8>5r z?!+qJ`7EvOVoJZgX!yadn;M&AqUP=$<%_=;Q?23K_+_KM`|DVO@2b`#yU(nq(Ve`1 zv}Wq90Ig|r)k&&qp8FbxlpP=QU`)dGu?tgu+Fhzs^Q_0dh7X5~e0+EJlZoSor6-)7 zd8Jj|+!pbtYd%T2`p3Yeg@GKhxZ7rK&@D z)sVk)=PwT^eZ*XFr*}eB+@&k;rv8!etlqZxBC|WDH&d@4u>68%(%Nx`{<_gU^4e7B zF;ta4@k7Us-fi`LYUS%gJDxsSZ%kT3+4l?bTSn|lnshty???TUi^uQtSdi|bo%W$l znLR(nosKAb_4_W}o}4)*Qht2DqFafdSC+W+;l=oCV;Z@+4{jOzN1{iy_~0vPLl#f! zQa^6owem&AJO6U`M2+;NK_ialOgewUJKuT7-t^?dlSbRJ4jg&Wy>O{DE4t^AK&7lYjf?5zL`7CeG6_Ix907<^7*%Rr8eYDD7x>QvD@i+)&{RGw)eC( zNE#Xzzs|+U)O3zV`P>zi9uI%&b>RD%sck0b-7&WFdG`JBg2tb2xJ`+9(?+!;y=>Nk zuzQ2{+3p()f_7|)iupPDOlBj!Q*z#?*uZl;&UKsG=FeOG`b5#PKCQ{wa=%f~lDfao-d|;w z_v9y?##HHg{@Bs5MHTl~eb{5gnd*OUpPaYu@Bv-z`z_rAgYrtBDfdIWn_h>e8x!ll z_-H({@6Fb0-*4EYSIaIfeY#tX-fPxOIyqr- zq2}A}pSP8n6_)d7@2$Tc4<8;=yTpWF{IW_kZ~o`3=k4SFSvV>nqv5B)5A%mt$$E7! z<$hOH#)n7s6AcSK{#43k^qyD6F30#5zU&C*Fw3Y4=;r`Mv*mRCnR-w2aL3 z!#N}B?`Rx9rQp+$KYKZ!-;q8)aIEfal`el(K5m#C_4rKR{M11G$=iENd6jSr+TOWz z&!?SJb&Km{6b&iiuCX5~a(sF2zNzcTih}Y z%UbZ@>7bVftf!xfmakW}zBlO9nI5XCbN0WuJEM5zp5_Jg#y(vC`BxPm1S`UNPlJi|r53>C1NP8nENZwRdO7p0F6MJ{X=k;@9~8 z>3)6GvnsY8G|D`qSLZw4hvuFtw7hn$CLO9JCqKC|rywXnJ9E(G;I`kd>M-}G%6O`?>oHU5e$^M%T0URjs8Ra1jg`MNKk}x+o-IC|pSCO9 z`Ij|6Zg|nG&c+c7cZ?}>`qgs1@ph5s52ha1Z66)hdT8^)gS&?Owx#Z#Hl-$&J-wh_ z(x5GFBMf8jCuC1J*mL!sq~vRp2J|lfB6HgN2S;l?o&CC2)06psf0(*^)Ufk+a+bH> zb~=CS^0^;p{dFvQ{q+SC-c?`z!|N~ik6uq&Sh>=fmTjlT&sbA5Vcp9PXN#6Slf0^R zQ*~U_FS|}`C~7}?`eVVi(2S>V$KE;}Klhzvy4=?NAW4CUj&e z@yxBzz}!Psz0Nllxg`sA%KbFk%Oy?Reue*bQWa_xFBaGKE-UXPcdpw=pC9!i*6!Ca_xffZuV>=d zQ+}PseZQn|?)OW4FK3HIKlyhO__ajtdb{7}S)#i~K&RY*(|%J|idviTU$+7Non}%e zEV(%z0V`I^PUK~Jn{!uh4w#lBJTXqurir?ki$$jw8*7D!i?{Qzj{L)MvFFwj7 zyYM|86egTn1V@UD3{>B(8CPK!8R5}kVo-DRE4Bqf5zC*2+^c858I;l5`&s6AP zOLeTssD?sS@xKV9|ErT0%YQq$f2CGw`P3*>x4I=aV-%-bVrI6r!pwNL;+`5s6;HH$ zc0gc+(2YjcoY81`a4V(dl=Yf0F}^kO-*DtVds`bO_8-H@bZMB$x~(~@Rg@hSr4=pP zU}THZ)GD#5H8*J&Nkg$nuODKOq7NZGV;<@cZ9|0&cCo)lq*jzj#>mq8LYV1D=M~hS zL?eFV(8xnadf#d2?E7T&Cw(01NkT~%i^(V!Z;FEUqy)1jxQWflG~FhvD5!`0N82KQ zcv~8;$u6d+Vo3hCB9!?V)t0iF_2RR8aG02rqE^x$%XG7d7=S9Ae!%=-WmKX;fBe%j zh1xaSg@1p{XV+8|da(fMyHcnTi(b5(i1ZnqqLe~$sniJ4V}3y6wsz>x3_ygJbkt!7fOFcH!j!i;4Y%dHP;m8;pFU>BJ~ z)Dg&GmFsbKrrci0F+{C$GZ;(>R*~OH9f1K_|JAI?ZWh-&t971woiV`>ZO~bSzKAB$ zRcEo<#q*EhVNQB6W0uktFS{;57i}E8`n@Ec}L_;*tmrP)w<851ng29rL)7%kf6M1-Mjsx~4>>!~xLB#@|e z?x`;7>Q13vdYysl!cShMWCf`7LLVB#9Z-4MOw>n{H33H;bllmds9odk>LOlN9rezr zOE8KJ-FN^-@nQf5u)90-&bK=zQ*TSakh5gTyp*UgQKW~uh`Y&@U_!MbMWczL9-1Aq z<5WWvCkjx~#bC6Es+D>2AYRi03-wnIb-bqqRiaCJyO^4xj>4n?&EH3aiPWCzC^3Bx zR`En0-?cYnz+^W!g9*ze+V$d+W;qqTdt)jH zlwFJ#gSgRxx@@n{8oOfJETZ8$ z)K59`x?xbO`p}^4tZi0kQq|EcwF*XC|1|Usz^rn{KKFCgLpiTP zuV|yiCY-LRsRyt)`^R8(cd3S{H8d(Gv$*X_t7U~<@zbIEKlFu&Alp@M!F0yV!=&iV zqUuc;%q@_472mo$qVWiX;r{h<` z{(^<@8i<9ku+n3x7f*uzS zW3Zugdg%7X#h6N^*;<1fa=#^L+o(s|3)@o-7DanU9tCVpf2Vf$(%CR?dH|k5?9JsY zjI3G_G8kR3llJTF1cV!=DAIK{%xcD9bRL5;L8=$iwo&I{m|#1#;t@)ESV-~pR+~t> z%PIz;{&$SJ(GXflR2Z#C7OPl4n5)HlS4FiuAr*yz*37n0`v2<3V=R2}yf`c0y09`^}SR*^QtXsD#| zdNZLSV?LE-$ZXU*QrbI-`Fg7nqh`#D zC+Ys@P=yca63^XS^fsHAmZg+Tn}b2O&%in`p6g*yQ#Fh+|26x->OC21y%$sjt7XHQ ziAAe<;*8?VV63GnQyo`G0=pg^#FAtv;`M{j!~%$!WxMK)m^emtD;i^CsTzs)8P)Yx zfa4`O=Vo#CXb_p(r0SA?xl3@@TWHxB+^L50$1rV|M`BhjX6lfk`wyjPX{`13n$B8U=kKjCa#pj8NkI7F+=^cr1Fa9*y1;{dOTm)dTZU zxmAoP7Nix!Mq>|ES*P}PwVF|_gm!QR-q-g?NI2=hcO3vr;yc!Fbv~?Cy)kH+@!e=* ze222YMCYetQgg>Z-x$^njL!|`Ld{`HpOCrR|2_(J6KyAKmsYJx8g&~vHe{gqgt1t2 zMt6`9okVxYs&<4qd^wi%kkFm>v{^*9;gVM2GZ+JIJq`l~D~G+pwijhLvd}IbXQJAJ z5Ee4&nAe!Fvl-s~t+sy~C4&K|KVDtxE6%&S8qL_n66Wpt?AsW@?D2#RjPhU#1vk`@ zQ97&rKjg?}`8Np!t(hC5>@g#o00XO&Gy#M!qtL&u6EJJi1b{*q*aX;(k|VT>!2ynN zx{#3#0dY4#9UB7VX*U|>%T2_zks)v~+H|5#3avI+A#;o+B#V9nh__b}gX(^ogziY>w-PO3}%<*U%_U(>1ImuR~rNF;tX(=dInm5?bU(+0HgU$`ER`*=S2q2#T$kOyNlC1$@-Expc4WbfO+REGiQM{$m0M_ zlyV%fo2@MNAgjQqfzX+3FAO>zp9Ty%-bBfwb(XrcsMt;I?n3kq^dG~<$rW{17Li%h zs2S-wdq4@47A>=}^S^+D(;*6rl0`+p2Dm$mNcaNfoUJC2wiikcPRbIGY;~Lm8wUeA zm-L9I2?m*kOU4AnichO)_AS5wwhVS?F$=F{!ycb5sc{!EkJZr_J1iCiT2W0v-}2U= zF_TTCX40$z&{?#GM4f^(MJYS?Kr1wJkajuj$Z~<F}?h2c4kl1er z%Chi22{-(Xh72|lU5(hg9Y+$DHTW4L&Y6R*187X5&nTJ>01XSbk#P4F2ti>@68h~x z3Kqu9MXl@Cp;qWk*{kTjjyzp7vWX;`eif@iooRazppIR^qSqu^8>%6ZUQ~XL=5*M` zRp(*B*3G3=vB84q4p9+Ul6g?0!}HLKX>hMNn=Hcj1vLbE&!V#PA%fFI<%&II6qT-1 zb;R$f+?@HC_|(Jbz0Hh05v9_QklTVg!gi?&Hk*}x}%mFuAVIhQ57O35wEW+m~_0^!XxSS-tk5Xe~C|<~7 zN@Il=L71`-LZ0c{N2yNi-?NJ`kbxwua*U9TTm0-nBLQ(|X~7~4Q@04mQ6Q7p-yfQ( z*O>sBRJ3jmg!OLG3R*Eid7e}fE+rOj%0a!Aw-6^_)4u-}wThk1Qte_$qYJQzq!`bR zvrK7oG-ML2^C~78PF#Q9+Ex1E8|jn%2u){J4Uu+}IHH%;0Q|GadSacF1Ny^FaTE(K%R4X_I zOU=ts@L3$TpxFxT&G^7Vs}wFI;d8iX=m=~Veb0~(JBdrWufQO-P^%SnW@RuLK^){#Y*AW~c~W;5zc@uOkbxxqNGYM&;M;nj*oZUM zV2;{pZeFN2Bgn3uuKAnS0oh=vc~sZ3piteLqVTWNf$=NG0(W3{IpzAtBDv3}f3#$arg} z-I4S=3zd3f*Fl&QtZ|3U(LKdl>#eBRbC)bS z2U4-{IjXgwNx&{jLJea!VSSx9qCdc0cNd&Hg#QbcVGEJ02gwL{;d_AVB-$C<{AC1q z*13(S5TNTN?z~V(y5O)u1uBUt8-YPsSR4TeW%bzKT+xb6sEAP36&h|3FA1bc$d&nQ z#?gV1miHSYt)BKjbz#tElpOwwyAIFEQCJMx{UkD+1T?^B%|{lKgjzlAeiDBF8_G$j zwPFnbwK#Gpb#5jZA*~Diry>u&6<56;yMN<06b#=2En{j-J$;@}!+?x?I%*4sO*jjf zn(+oCi<|*m>e&`l36Ld&hodS%Ea5cEns0@SAQr|V$BXn9RGTIHAn}qe5q5i=dCTRL zNiLR)d10I-JRO;$bgc8r^F)*1Si?t>v1u=QB9kVJ&C zl9H}_PmMvy^QGE>lMz!|ppIB@8k@ubL&*ixcAy}mEFZoYWetvvca?+^WvvdBH2}uB zWVM|b``&mM3!_L~PKyUesT8dy5m43x%U~Dj_oy?Dy#>#EoC32r4Vop)8ej*x(#*}c zZE83J%7n8m6Id;ZD%E=K!R})IiZi!CL0ALWZQtM3@MaT`GQ`f>N%D+J`hiEW9C5wv6sP7uY#0OovbbS!_C^V30L{ma_EEeV8dGvv3u|$X%q3rBoaH zH%x)Uf$i>MOEAuEM`{A5$z^x!N3#sKI1j@6O>k=f)nsAZ?+`wHj2jw*jfYj4;FWev z+b6XC*fGc#F5dl)4luUDu;Yr2uoYfXDNH#4A#qt(8@ZBuJ5%$ph+OjM0jMzG)x(8c zg+N#M&bg&<@#Ed#SP8C1x+q|9#d%hin|lzIGPn|cGPoMCpSVt!Ly$3-g zH9?eU|1zZ|8E>1yM=*sSz;!rvg2-e^!gEC+x#!o>)rMbXN{XWgBw;@K-2 zAGCn$8+#1(F~Tz7GnpkJ58>%CV3&kg%!hu3gVXa1SSS33wwlHpj+sT2{Z+>tras#1dvrZ>ueHbP2dwO`iDgIPOu3v z2*y|w%CoHFNyvb)VC1A|46-Hw4GT|^P`aE+$ZXaGz+j=}6gtXm)~FNHPf}kX;=wOG zg>sCsxFNDgj5PsExSYpn2pMQ`=U|dRYl1OmVP6t5p~d3bB%w9o&UMBasLb`#Xc18B z?xYi`HcXlctH+WWXCU$Uz>=iGB*9jOq_PB99l7fmU`<#8E)kT65`4*sEet&;8cTPE zEKJYC`VfsJSG!qE^~LTpVfV4{0SN)IbP!?Ba+Hgih$!{2{#nRQm1Fj=mjG)f9!j#< zA-F^T<|csgQBan0@U+!9ulSUi!YC+fCLT)V*PqAmaAA0sT?Ej0hFGJCp*C6gUU0Yw zOz1Mhs#$JQt;o25S^ZoQgq}V7jH_n3O%anoLg1=9Zhg`pVi`%o{YknA9VT>jlY3&_ z1x%6|wvv}>=f$t^iuq-D#TAW$knxu=y^OB7pk;JLNrzROd{<9Dl?NcgFGf(#q6o8M}s>H zu=@#@apP8|XX3ABs4ojEUxSeOD=yR6UqC{of4@K|`Kz99${1zM&~Gj}b8Kk1 z$aoX!;Yrsav>H0eV$CpToMXs!R4&05ZUCJGTQkTYOYf4DqBbzC@D)qAH3O?|-@;gb zxPh?}+&TmCasLNgBpK_#<{RpG#YrrSGOs0Z)dcY1@S9K(;H@XNB$HZ_ASrigW8LU@(RLx0 z^5#)mGNf}~O59Q)7ybhS6cYXecvo;&N@L8rg)sthrNft5Ek*r6R!O2Q*2G3=i;Gi5 zhdUKu1Pr!%lLT7}3>2%{X%Yc!<=}MEZD4UIzxB2{-d(a#t#QV6kvc$1^odL6I*O2i(q0)VLB{KhfpE5 z27>_PMiVn;(VtX~c`a^P71*_4yRmR&y7bZd;J|?;>PxU|ae)7hdl&-4E<2I|ySNNg z8jQUU8KJHl4s`%*rnVNCcCK~;q{@XJ9Pikze&5FN;=bBLbej&9Jhc;u4x_5zE}~v! zX%OS$D!L4l_jp=Fo5(rvWFE`R*7JdcT{|u^z-*0nhTmk7_)uM13C-Z^CZ#!ba{vab6sb!Q&8VB}w;{I*&hw?vvlZmFN@$t`#!gO!_C-H0+(l-kqb+pQCMw!Q={IAA%K|frWoSs9-SPyfOxJLoow{G!G&`fAr;b#V1>({g`Y?Wj_a_;XCqJ&teAzJ-#}R97%DZQ zAiHa=*f}ga^9ExF-m=aqZUnl}WTEXXgp%V@^bd1fTo_8>;vKOC1tJVMWR7zJ@$ zQe=b3k3wg_+4jGKR`q{JbrQ)XhbEI;y6xj~*Qp$nTwtSBY>1ZScxGz+1(|dtP{;;z zTq>CAg1h*2f1%PZ@6=u(|LjJf%RFu_`~fl`E+!iXCYyv@8F z5~36gxi;uM3lBr+A>-!E1`+cQki!PWhb&HX|1CtiY{ecwkWQEZ1#)e$16+D(=V*j^ zt_}6{fY%o10IR}wZP*5s!GqwHfw$&I0B@KV&K3;3CKCg&!=+#{34Mv+I1!-+=cdsy z{@TFPxS0>1(Hjt7^84ZDmt40ti+*+{m^ggK48n9$1d}A_WxFu6+lrU_w zSV=b9q;WWI^$O`ll~$^B)s|r9pkUfYUifl*C?g0WkL3 z>~dsk7svp;&@f!@S|#?{q!H1Ip(G{j#gu?ShTt4!2Y=!%`v=KDdp(5HGrC-bK683K zR}DLCsYYU!47YY@G)uRV6mToyL%~}+hz?7m+%$^MmSSv_Ycf0Zou%VR3NJYLF7F2R z+S;M<2R`vK z*R_N6u(VoYSe)nu|AO3POm#`f)!IB!Ex8z+5$tn|?%7DhxV4x>Rpf0Mff~cF9cK-$ zwU8IaLGUZC8#OVw`Bf0KpBDzf$P2JHNaQ6US9!w=RhIR_Zb96g^x=|>k+4=F6!bIm zPBKcqOEM<&>k4T==4D`;4(rI^OVY(Y*l3~N=n8``ZqBXJ!(hk3hWqJ!QOj{@_;eov zQ7jUE>FSuJkEkfXkC!4xTsqRe`s9f-f8YcndzqnT0|vp^{93|;GUmz16QLqmCA7`va{x$u9XQoc4L zsaIi0?{u{>SY)s1as8xkJj%PVl$g6tqBiDNgd6i&rgXH=NS$#E6%=@xRsF$xfi zs06JGNqL~}129GG)J5!$gZh%x-(92iWTMLmoawKjdoz=rf|eWMCnK=~f$@?fOx~MG z8f@ffyhRl;-Kc5^suCs*?Q@RTgr`8kVQPryWxj^yh47mYsc$7Jh+9z;3aSEWi3y1L zHjMc&UFlaR$V?{~_V`i|0#8J42)YDh#@!NeG=wjNyCO&gSJ5<0 zcUpx-h$_Ehv+ub=MvFq?5x>S+l$o3mipH4~^Q}BW*GLKw=L%ktG$R2^K-OeLD~FKh zxpf$=9^b4XmK{N4HLyY`$DDnab#K+!mzV&44<1rLZpo@h6PY z1`0QJ!bKQWpiDx!2sFv}Z0wfYlgv`^9`4Xmk}^f6dkKW1QBep{J3D}7Km(%Clyn~d zPmw4DfR?Ni@n?#Vhkr8?!>_^+4GeGx0_cno^kctm;k#JLdg{ z`xw5DLKLzhWlal-M%6@;T`548V$l>StJ=tD^on^hU)v%KO_8#yJwjQ>r5nZZ+{$r? zGvlHDO=Hk4NtW#}1BgVX!ayIMrQI>8n&~n-Xg4DI0#cmPSz0s}WywDwl@Kw=EJbVt z>FG3*f-}o|3q&825b(&t_pzv$ofKfV>k#QCWxTfS;;2z2%)v$xW>gXY!X=NBlpPhY z0~S%KqeIGNjqy-lc?Ad87cQIzJH)(z^C2eY?CxX}QxSbE>*eKhErL0gcW^XKc!$ER zDud}=1cPB`1(3~5;m3-UTfIb5c2|(4(1~f&9b#^^Vo?|phHWEO*G>V*N@;G{&pj$$ zd2m9JRt(%>=$Qi!%*6@%DBuB6vW{>v7IWhZi{omrb?)w>z-@o{(fCOTelmV1i!a4B zO7O9PoJZ$r&=f7flbKe6mVqFbIX@ngpkpNEny-=+o(rfQb$bTF-ylU)1DCBlyDJP3M^UP$k7f&c$p&QIT=<8m9rBA zH^n-NJXWNpMN98h_AHl@K#kP}&~p9^+_Gg75AUVC}%rWM_E=orDZXi5GG%msT7wBj5I2&-jG z9%77XwD4(iz2)^7EdZOIOBgA}n1xEC%Sgze4ddYeZ9RB87xgiq;uJl0pILm_$en?R zm1O{l*qZ@7$kQX54_Ek1?zG|-WD29!laok-HHDv`Rz!mt(Pmqi0$l&wBw$m33ClK- zj4$n=-&Tqkrrt`J*NQL`8kLC6-hGMKda!&hJlX^eWyCfRzmtefK_-wYZe%`>NwB7% z5H8ltj5ei51D=VAJWM!PShkmB5~^`Fq=;ea52QQ^#Vj;XX4bT&6sRUK!$?dD;%4zK z1hHXcUnNwNly}T~3v`8{n!O$ps&UeyhVfXyiiR1gc|S?0rgsA@Jwa0TCPR^oLSi*Z zxmzY1rirjxdN>dsOr3`7hs!P?DWNr;q3}|KRt}yYmZ|KJIj~x%U^PyTQrZVn1*Y@p!7>*Fj-7e?R}v%UJF+T}PO%%vqZQgZ8gEhWV`Q+W zQQiw;^*%4))o`d%qoR1JjgI(WZPAECb|Zz+Q3d<&!%JBC7`z48+Yn1+HzG`c#jon1 z4}O{;4^Mg-h^RKqmxOmCPH3E^Ze4U?Pg-z*WaYRL(b3yLno`IjU+z9f=;u&8e<3t%; zAiCnlieCz%3nri-OE>-Kc&wc;5Luubh*M*dZi0WB-^T|e(uSh9Gjvail}9FiB*OLB z<@?KSi5mHyMLrlrtQYb~Gho6+2fvv=m#B#rIfK=1($Rv`5^hJ=szrdQ1#|3fl#e;?av% z46LWL;la)q!e^rLQ7HfKC*im#{`Vs!T+at0ei9Exym3WMQz=abg~sqy)~%0u%Am*S zd1ruL?D3H_-z4{$*3(F##N;FqdunQ?rNdN9u5HmvUx`I8z19}Jyf(DR4k4cmki&&C z`&29j`QXE1kPihd25Ap)Z>-3b`V2~a2BkiOi~_M3s6MwwUUVINCrR^zm%}|{F^P85 zFh>P{1_g-l+8VVO-2f_>b~{=ncGS|u`eHzoM6Ubzq0DG(s-lx|EA&>02%{k0pClM1)w=80fVSnN%{2 zTX;6n6cY{SM7fF&Nae37_+JW#Q@aVaEq8(Y*%z-JMfB59cd_hyO{~hy^DF$CqMsi> z2KkA+l^Qqk*Y~J=lM#5LOQaTf(#6!Kn&Py(-Nm#-O;LO_1fgTw(L&$b7Nf3^vw-=SM*XJ6)4IlX$p&$tx=?Bk|s9Y%4+^?Vfm3N z?IVjx*#OF+)uLScpeJ%8D8c(^Q~oYr)Z)#kvO&zs#xN`S&B{hID;v#1>Ml~cYMK;g zb^f|f5SS4JCVoCtCFV5J(C0W{RB3s$+Mw6}G}7P`8uW>Wuiun0 z*%kEeoQzpTlAAc)m?j75`~i@S{-KeyFe+hbLh}gA)~*SBhPJjczpGd%)2(>ij|XMv z@Gf1(pynlFscSaXgo+%OU=IpX-S3PHg;KCP(U7ay*;Et5GQa=x35-rDvV*R|-b~5l z44#e;U}(iPs(_D7AL;la172*k z!w5M2q$8cb#xSg%%#X=|?Rqf)4#9hrmAA@*7F@Ob`~s9+{~DiHpbszz_m-%fKB~a8 zzpXtw!zKE(LR-gqB}Thx+2rzo~4~MkBD5YS@`tCrYY0Ok^i1d$7(!B{_L;m_1kbgh?k%*ESxPB z9wiD|W7)U0q5go`;bktqH`5t=B|4e1B1zW`NoOf(f=oiBKYi@T-UXwXo`TY^lesiZ z6P`?poUiF^+H$&GmC~_UQ>E%ss>rH-}wVPZF-=?r&FmRBt72;Z9YUv z)^?nP$Ilz^@Ea)UjK{hdg`3Ec5^y*AP><+|Dl=*!9K29_fQA)2?(9%#c0WBnjKd_U zUwi5;whE{B=mo>T^y-F8$9bRfU-+6{vjgR)gD9m}?2Y`~?%EF2BODs|LqN-Vqmw}$ zISC#GdPeQj2TAEN312{Iin$y>Nq-_K5^)Rv+V@7X)!#mkgFYadLN=4siR(1O1&s>o zq@jWxGRaCzCroUlq`1zU3ukzIo&(bZYO0i!a|I?T$GU1Bc;Y5Tk_r*uS2L|R{6&&$ zSQV~eHApD6O0MAmNU_+89a_0N%+bwm+#RE+e+$iy?uX$cJpnzz_gK0E5uWwK#BZrTk~3OJ9Iblr;}cTuVr%%u%BxGU2u(~Z6-mT@@kDt~UIMA~F@8B@PcqJxEuHjXz;o6_yn)hc;&fg!_60xrzn@G)4U-srWiF za+bwF!=`KlVd|cathWbfO8QEw@imv2VSwdt_-nYUs4x)Bl;Dh~56*_aLM$RH0|lc; zgLm8-2tIE4FU!VtW-2(D-zw;}ZV}q)oQdqZedyAlL7Jkz7T&Di8e42aW7Ee3tHjws zP?oR5w2eeD(_q@AfJdpgBQYZjDCw)Jd5*$7--wASEu8SF2$AO%;VP;P(G*o#m_CWq zqrj7UxJE~c@EMVX#6}}(I6g#E(!)XM#N5$vI;K{|WBB4ji3m#4s)ct!(MhYM{?IQ) z?-WL7l|0@HriArU+)US$3{~Bt21qiuC)R!k=KgC1tkP1d-3w^mFo#%mF?rfO;ceUhiph(}|BzqWN|3aWfwKLkPhV`yMH&<|9C z3Er&L%1&gnfP8FR`-iD0@nH-`%+9rTzR_BdIt|KR@n&$4=rWdY6$XRTS4~6b>OTtc z5a-5fibzi+3-B?x2vKkzThBUA`i3c@BnpxL z7^Ka9926q{cI8wJ za}(=HNKY?#ILBvUvLc?VgGIn3Ocpt-INdo5g?^fZVe*NFM&6Q=xSo5Hu&wC92xtBM zYkK|3q#<-K&w^63flcga$z=iEGq51*s~~y`YN8JTar&p(Xrc1{aFrN81)U)Vjr4HQ zB^#>@hmN~=CG*=kJ)IDR?4ebO-nPo;?ORrnlo-LC79o~S2lixK4sjE?vmJQA zncHXK^A};+3U+W({6e%>zW@%PiP@}E{QajeF?b=UL8T*LF;6HzEe_}3z7P~cx`t@V z{U&H*aap|a1>%Pm2~C{8bWnVobS6bwvEg)3f>^Z(b>>$I3dk-BgIKl}c2(^;nh3xD zVMsPnwMQ6EJacfgY)7%D=jUkR{G?s{RMAd@$*PqL5(*~gpx3LRyh?JjiqAu9J@K-NKuK)(9QoPa%4k^$VHPb zhAssf;XB2JM5p;HKLF6n)&dIg0w%H3o0yq8|3fE$9Fy_0QiDz8kFGd6rd-MBB7vn^=6l|BYMVgWU zlEQsc0MHHpMVcZ`C4}!vl-q6828h2GX-fDzxSaA0Qrv&M+~crCP%2l^JO?a&|8gAa zC*}ZlBcpr7@gfIvKXV{1n{H7a`DNCx4T+6^Vi_z;p(0-o zVT)H|$#nG3%ub*my4)~VaeXO{=f&1&!qOEtqD^rh+7tq6lkD8fCTTZ*DynKxbX_5& zHieMdnD#>Ttx7(tlFz2>C7ZH`B)!Au#dx`sMa~+Kp54n7AYugd`xO?rUOA1w$e9Kj zP;$9~iY%-{LM(kLOx6Bjk+`$;4t5i#mctbG+P13w){q$ z$Xg51H{jT?LK7gWt;5XR;!ILkbJii#@DOMq_LWNDFPX-Qfc3~UWF^%k)iiBAWvUv= zesrt2L-P1vNG>(B$_B_6ctbNhZlccm#7ejAZfy9kOFxJna> zH)%}1epsa`5nz|r`RnT9mJJGO5uuw<(TiI!N4Hnuy237v_P?{mjMG|#|7K+KTLC~$ zTdj$42kqm%*mpA;RkbUts@&$=l%uyz zp&d4bZrBx?VOKu-Yv<1aH$p&|)DpX-6%ydY=HFlzl!G^X!=q!u@hO3Ji(v*jY(XFC z%q>=L0djmjVpATmf^tE2h=1xYq27 ziM1;x7H=IWpTm;b+0vr@3KhyW{;9pt4Gi^_FUBpKX;#qB)Xnfj-QR(2#V^Sh$#h)o z;z9=#<1`VE38rtwzOF}qlIxcX)^UqcbDNO(yj0WIL!_02Sk#gJ?O}vLu@ji&XyI>x#ZebO` zH4;8c?#(oSCKJOF(YrL^pN)|JAW7Wccg-vA>J7ue;j2KxoCPG}^ zswwFwiNv>!43{nJMcG^j2js7y|M&&bZ6a4wQu0DdE5QVVyP!C?>8F!A8sU#}jI)o3l=@%dyTgOt{adnED z&PdT_yQYNxe{MSMOlr7K3he=Dk&_}>VY2vnALjDLcFd)t8^UWp;JxQG%un?lV0AOP z!xcMZ2kfP!M&EjZTa)Qn>hn9$hy8P~sa$r_1twb=Jaz@u=Rv0IB$`a0)Zn=b$VPn! zc4|sNDP)q34WR6%q`iaca<_sp^(VsVeSy=n!h9$$7115`P&}Fi z-P>~uU&gO=2-8#gOOTfc*#nEQ@(`31ALa58sY$Su&Gu*_|JSXCt#T$fG61hAb1Y!+oN5HU@cw7VFts+ zD>wWzy=I82FanDZm}^FuJ$d%?H;$Yt^D-n7h6EG;W0u+=MB?^qCMN*DEjr1`M}FTFegCd$*HLjZV_ zHqsBl90(#t{2V47QMNE0l_Swzx|rqquO7#$KkXZhyU+cw-PKND)n6>p~^qz*Us~UDH5lPU2j^U!%ve(Iatu83{3-XI4iCnW{$H zC2{*!o(UY!u_U!#_<*HcD9KNgMgB=FRBEpn*Ft)P+R?01#M9oRVfZd3T^{fl8k_?5 zPJmm`8yz$$FIaQ{Q2oDK$^~CKCMKHmI z*Y`P^!WV9EUIZA5x~DN+3pz#l7e*vFViHYI2UD~e0rL@IcyR>kDf0zPg@JBZ5aQ}f ze^J1S{@{Bs)HmGZ2W$BO_^lrJ-0GFnSl+VjBiwu_qRJF)LVz#jy4@rgp^g-g#LZSc zgU?Xofdl=a0M3T5)>>t@a0(FROsmh3S%Ja!!9wFx#@sdN+snc+T4#Ax8!kp}!ACH1 z(!yPRpm_9=3rr|IR9kqQLf@2OYM9f?xl#ZM11pxNiTB61o0*?|n>A*_`zi&w`T_;; zIsijOl#dZ8uzyh)P(Yb~@g@)5TYp5ODr~~k(Ff}h@(1?Pv`R9g3BkpP z@+}ug!&PRk@j24^4WX`H03~h|-I`_(jOH&@%E?8R!X^p zDcc{&CUS~Iy80Ngi5Lx024BScoksXI+Yc9zjhxHAc*npRX2PpEJ*h^|NK8H))AadX zAGn(wa0Zfh>Jq-}U=jB&X{=vkob-4O?G8%kcOu-)$As8cC@y`o0_*4>5CmnUU`6iQ z_=^~)ZfYp9$!&sVz^n-WPS9+6)5^JCU8DivkmZX%5`Y~*|B}+;u6RDc3(>SR%vP5) z5drjdE_?!>R0mPwm>Br*D`~ZCxha+x4G!ua>UiN?3Q z8D&g(>;k{oWe$_&dLzWgE9h|EIxQ`U3EL3B2s4E*I!%ejl5n(ZW^9D$d==SVdH_{&IxFH1N{U+)F|N5|sLB_+v23ydx2YJUSs zIGT8i^XD`%e*YVmBX-}wDHrDyI{HW@66Tu(R&-mq^gPiDq*GK54AEkLa7o-3dJCTm zbW#D1=q~^+z4FlrjwFRd{|j6K7K8fJpVH4=AYVUC2zMx-(m76>?ak$DeBY z|9b~)%mIT<{1sD$bW zOj0K0{R1>rET1RJ(afuw_=6D{yAgUgJD>VRcY|F1#GlB__f$@|s9z4XFh9gNUg6N) z;}-L9IMg}+BBYD7!f=ILr2KSA$myPs5EyVH+D%k0K>lxf*Y6SK-vU4I>H@l{qK(W2 zZj!+JHZ2|e=A2aPF_H${rjFD79;a=fv;s;4sw-(>PmuQg9hs)IKbq2hqcpw(FX}0_-vj~5v!ZZE`e(*DnQ&J8q^WAJ-@;78>AJ$3Y=GRFgMcGw6TO}hg6Dbct+som@v>A?I8LSRpjjj^T1KM5Q{1%hCRNa!5IEQSE1UYK zWn$Wi64{`$L43s>X-Pe`nK8_>Zx)((bVd^pL14v&jKq@{rITXaYwy3IU{#z?gbbTrL6=qq zR|a9#9A5*c(}Lz{z^i`brj|T{P{cqrUmeq@f*`q3nO%)eE)Qz-`(*;! znx9h5?5X5~?Q-I)1!tt7S!MZNyjTjmJ_cAxW%=HX&L=TcQy~I0z4oDKMX{h=m|3fe znH1rZMbm1;pm|sdCd}ht;JXN)++gv<4I^>lRKk?3dzUq!W26toY%S5C`LQOSJRT`k zx^eBE07%8&9|fvB713&U2s~~JYxVpns@01(T9BDY0hc8s%^y)d(IJk{cS=FeDvTSG z%Io(jfxT#9+-y?$03pEOUAF#PQnzqT!76s+{0sRv#k|59P6t-4i zTa!6wA6eBWQsYKGDgf_#1yUl+-m0_#eFuPb8IslKM^x)>cC>Lb#oh zAQDv_kY{QJ&6Xsvm@$>jlzLdEoc&?aYtfQI$R%C1$`Oj z>R4Y>w|YuI3clYJt0yVCIY_RWt&TOZTX*~!=liPyi(9sLdTj;|*TwC_6kh{VF@di_ znz>CXgvKVwh|5b=Aqi)eUc>K%H=b~i>?E# zsFsC!!#24NeArM6nJis|_6c6~WW{qV>|7VvRE34so^5rh_dv4L>zM%D->pY~y9K4c zq3N`s9^XD26nYZ2THA6|U}-59=1se6>H}M3VNTt=DX7S}RkhB6szLV4o(S&dHRo z(SZtjML@q>kcU;jDJI{5+B!Ayr^|=Sn$oz}YD;^Wl?po3ln)!$5n8N<3c9`-pcM*2 zSt;lf0iClTug0S0fJW7o4_O-(>*3~*-&+^*qS6#py#-j8)B{VFO9f38(4z`sxm3`> z7Bn@!zRW4qn}WJ#fi=Cpe2Ah@(6a*iK|wr_P*7SnHFj?xHDY8aXpw++G(e8jzEIc+ zfn_!nn3xs{yDkT6OBy0aYFa4l9f7s`j`O)Q4P}WDEvyAuxfBd;q{yfzh25Xa=)Btq zAy$Wi!Yb!cQEp?c$Z>dl9(ZdS3!WH}iubj^BAQs3H#mC#Ygt8Zb53renjTA1k)O(^ z@^70+<+8vk%vS*HvZe}iT%271(Wjd#QP<1g1QuwfFqS&~wr?Td&TFRMVsI$z)k5%= z^+lNsta_X<^JYg?%Eh z^Bzp;rJ9zwOwA2h+8`^?+!@2)YW8Ny(#^ucr>Uk!D?qKX1!P4v)l3u61`G0t9Tbon z!U;JDlq~%Eb=TIwXXMD&R$kdM3rIWtt3}l|wlv*y!IIsXez=I4BdgrYxsVgXOQ8?% zV%w9MCy0)(1KZNb;$M@Z%!)kEAOkhUyxkUlpUy)_HDJAfnzuvXhv!TC(36U_x*ekP zK|WX#r(Ho6+w^Q?UbKob?@q~S>c zeWxHdgAzLe>QtoFdc!+YK%0w%mK)t)JJPj4OX;oCS3G}2idqU5N>dy0vVi_nkR3B3 zUtR{N|0RNj(WqEU1++^+ZqEL98GUckN*dub&WKLb$hC?Hv$_?1mk{py^+%mRy&$L( zmt8>xmxDU0HI0*C>(^f0RXg)_>o)Q=>xrUH=?viVcLeNQ*hOy4>2&lmEWXzTH z{eh0OR~}>Nho4Ex^>v3Z)v8>IEQY>r(;b2nE|sqxn>GsQ8w>KjmZKwc>1BfD*mP?T zu%5OcZzz5iP@t1yc^~%dNwsqn#A>ZA+0l~;aikNCkl5D>I^G-4?^T!cVW?eq_Ok8b z{oLiuFu6aWsHX(pu(QpAD)yXSi zW(c*>0N`5_xm+@=JDe+ISe3*|fvdKBue;zg1r&Z>;Jq$qN1oF|;H<$4AAL3O)jeRV z#%vbu4Evh1ok~4vt43-TP^)Xe8uBRjX(#rS+L#~u^@eNc))$J3O{SpOYe8+>O9-;O zC}_sDU_H@G2x2cO=tlu1^j45!U1DbHe{2px;F`Yt`Bg#OLRV1j>u5=@K0?`!N2<9~ zKri(XGOW&ubxJ@y_F{Y1S2}73h1L%OzV%BOx!l4%{PzX^PhY4?tYIOsYBIN(hF>K_ z(Pv6@?O>2Tyh^Hepr|2$F6QE>YSoXq>%n<5FocFb)KBSo{r^@#(fuJPkJ})aVlEpB zNS#Jg`_oFfC8_Yu0$;X(Rvr|%NWa39hWS$CvpN0ZD3GWioZxY~&r?Q5RhK_SI#E%s zVZ|lOfvtx{oE%Q~1xsEQDApgtd|c0vb8m~2D?uqd9A=i{NTdc%RyARoR+mfiU?M6j zA*=yKYA}Yj{&lslMr93F;T3v)?yxN*Esokbl2ih$7DP?4I9ymz0%yn25@OBLTD_}4 zL^WCx&k$&m0mT`4BRCvShj3^J_tFHXz{&9L8(~fk7b)Z%QVtj;jwH8j%MfZg7DD7X zw==Fvij1~|@(5J3_ZlC8+}$8f z8|O<)kc5*Qn-eFBfXi}3ilsL<-N(HSEGH!-ca{=pQMP94=E4TaCgl^;dtgGcJ`Y#4 zZd~9nZLjl1R%JXmiP!8!4Y@QNE19MlVv*dvORK3=#)ucQBr?{6(f9dq~t=@5YE7530I6k6QI*`urJCs zI$zFeZB?=YE6Tf|#Il!$*=$xh|CXKY)5Bn-EDws3T`c{Qh;JT>+>aolG$-juedW{ThLD1izzRjxnp(`3{zzT5_O1pSMVH=Llob zb&Pr^+>Gxxh1P5ygSpSKfye&W1eSE8g?asNbTcr0lXb_9;ws3(zSpr@DFwn~bIdF7 zgyp;x^dGBK+&VgXDliVSq&Bu+N?=7S+N<$63-i8hH4Qvn{Z^0D+T0}EAO#mJvRigz zrvuxal^$uv-=uwGTcDI@NWrH!DP^m^2_7u4tvBPvYd>BoyJfli3<@3_FUTDJS^_%+ zrp-v4Ajn9qEqJ31Prz@RAU+PsU#Yd-c?-xgh0I|O*<;-)DNxUSpJGeJlY}9+Qt(2t zR>|cXrSiVOYEQH+<+S7ebn;XS^J;4{ z7rfg&m{-xg(u|{1wW~-I-?lXEOOS)X(?kv=7@pF*VIFvIPP2GCK{1dzbe{93IX`l3 zF>AWE9%<5oR`Y4SnXbqPjlwp}hrrgk3~l8Z7MYiyLM8TgkjKstWXYJQuo(jT!h?Bu zKi&?3wzo)+h^}byx-S6sxP>uz`t1&Z)x1^lSmhM9egS6L%v-e%)^dg2c?WpESUk*Z zg`E-@@+WnmuoX6BA+VP`nAeu~7t+3ZGqFm<%22f2MWE^7+r2Zz9Cz@wi+t%d)EhvS4q?|=radIr z&F>cbQt_@wl6FMu$|V353DG@5UUxbzp`E-SiHx>Lc`T`$kv6HzbfXI$zwvTJAJ7>x&B7q>{3Mg^7*2`4ErHDS&~gCXXYy&m*6N*A?ORmULsEB&=e%~CdNeLIDpeA?ot)Ay~ zpDTmp;Hw0VaLNo~3M%f!yBXu)JQZSQn!?8118jkXVTmd1vwQfqX9|ZUr{>ADa7Rlathy9D(39YPR? zhGLx-P|bzmprI=P#r?znc+Ns0=ukfZE<$JiTqxbl%JN9$-3xxNMer1u$G^1-lk?u4 zi%D2 z!bqp_EA|_Ed#9JPK&2aOEtGkGuBy{m7tcU>RpOr|4lVluLh<04o<&rxl6n1 z3Pz0K9p8S7jJBpN9O~Z(GTo0fJ?>Uyc4t~pA_d#;R?2qxQ%mj#lyZ-P&<~1sBQTEq zE1M16OyMRrPe;~HAR*+QiGV5v636}&N+_*>1F$@n@E zyp{WcW_20R&jPBr95olh>bVv{9j74Mq7<`ZEm&VH7g`RK{ve=sE5bnw1@y!U>7&E| z*6}*}AjA?^s?}5y3WTFk=&r)yle|_ zt7vTlHh`=r?hRL2mU^?NVy0+t3I>jX$3fP!!kE>HEHOJoDmO^Ml+{Yv z!D62Prl!Xa9ju;=z2h1Tc8$W^s&`Ug%Io*mNM9r{t5!L969vs5P-Ipf zg}o=R)gH|2M$XfSMy0jkE9?VL`%-IS^swpU>bY#wE}wizt*+Mu+^8WxFtH;rVM+}f8ErpE$XL2Hrbi>fZ9atq`h zZYdU$sE2=Zw!)&V6Sc?kGgwG6u=}7x|I#OVcZjfuxnz~(XpuD=xmmZf-Gf}iD(5C?5mgY7g+ zY+5#qmR2rTuL~U-2Bn~>d-`}ko>I-ZkK8&pj2t#)#DwwJ-#lW;3a`b%KR_{5T_wt&xc_P-Qj{_h<#EFDC%Y|%yV-Iz>Gr%P94yYIH5V_?BaSaI< z&E{Nu6zp5(-pV}A5}Qor=mcnS_%8}F3fSJuGax)-CJxP{mW$#Hd;zEL(T(_b6eX97 z;tmD#L{Z)bB}Q{9STf>>iFp!Fi5M`7(c(p48jsVkr@fl;iCHHR`FCA=Tz7oF$5qOR7t95|=^oz2ZxY z&DHINr6cEfgHgfOMAN>_1}8pGk`Q@y<%^3_2%#dfoKpHtu;i%~&!J?CLW?BT)`OeN zVD)_!ETV2BUluEuHxT*dv0eqs^n6;pQ$i_^K=%KG(_p6#o@_iUB^f;2Wo7GI4puB% zdA2GA=n!0Q1nPep{TbHsv*4ILFYsgsQi_y|_Z3IiR&6@-RM{}{H7XRBE-Y6p@pF>P z&0=8yDb{Ym5+4}St62H$QE;uH*wvO&q?WsoaIyulkC9S*of0>H*YQx2!b>qy;0TYVALEDk4?|3hcm>s-8AAX`HvlaH#;DM#iIC^bpdP?V9ckKiOm zcy&zsZiAfvX?G0agO?Id>TCs9@)yGsXhxMFb@x;T?%422xUs~yJ((tX@eUa7e zt2^cc{VYdnF-UQ&zkJR##=nS|5@X?66>*QvvIHCwJB%amP3(HblKIkoK z`|BB$h2qE?FzleRIPZc(R5)q3B55DXBV}_JH4fdyi!>frG3j7wzUjWBOl@o4mL`ei zVUct*TOKLm9jQ)UCt9RD@*(AvN1E`C8#=Ac4qdt0z5yp5zX+n8FIlV+aGB*9FO+H1 zrSBr*TOZ_U4Qy64$z+yW9_?w+5OMn&N{GqxyAYPUQxtelL>zg64N5DY;p6qRtjy!?DI7xLgrdkHIfh-i2c$WN*v>q&6RVyJejdM{ryxEL|GGSX z)wft2qJ-+OPhYs0yqC}A7%^5J>=Er<-_psWymftj!AkN*OWU#pJPvmVt?!|UltS4< z!}+IZCxx7}CYG1NN=~dEURrv1*d2;D_*2N`VS^%8ik8O{PY${qnzu~8_o**E0da;H zI+?e99P#ih5(o5|boLinyc1J$IiFGOk=Ga;i$->L+7?1{X7B@orcVZ`7S)9OVV-L* z`X$)+no2J6b6;8wIdh^edt7K*k4u$n+n7{}Q49uVut=7NfmM`e+K)?>0pyTcvAzXM z-m=H$&^r+ZmO-BF@pi1QY(P9-T=oU6LKdQGkju#v1x~!owre;xlkL0GdRnkV7-G0$ zD`+ANrD)t|QMAC9pv`$MMIM}6#9V!m9ioT*s)%z1vCW&VR(Zq@e_gGd{3zD%U~yul zr+#oEhY_H1GxTlI^te?N>8h_l;(n$SE0RpcLWksWZ0A?LXmiCSiM;cRNr|dr@yMnz z7@Z6$+kDda^zOq^Z63m9Plj_c*cORNqcyq(KfV=j9D2RYvccJ>h=oY@mhqYLPL@rX zv`UinJ(PrhRu&F9*#u3*!l8MVnA9loY!3c~rOp``E>V#R5jJL6?_(LkitL}Yn>)T? zt-9wOu@S{a&Oxt;9`J1BmK-B1TIRRDv_$R*iy5tmlA?<@$st6iQSKDPTJKHaaUBC4+>B$pK~x(qd`7 z{~evUC_2S*M1-gm$s?8fy(dI5Vs=5s%1{VThT%L;kO#k)eK;19m~fz3Au2_KBcMfx zwz_82N4~Ur-b=)MFZdl>L>nQ3y_St(z>nM=Uw-6!NA5*)9%+yM-uue;b_V}@!E*TF zKJ&un;3dvBLk{}-g#rPvRqJ2{g%|>M3$2pEZdG!?z!K@j_xtovk_!QD3yqu*#95Ib zsYsXa2T4pAc5_N8Hyp`!)Ew#ti?+yI#H&S@yoP9I z895e>CHM}+#o))R&&v_7MlJhhMyN#|q83?(s)z|Hy2oUE%DK1XS=Q<%2!d)I4?(pK zhWg%NEPGrB@Ob#O;ECRk!?sdVR_~W$iVl`44?QPh`et%OjKvcciIjyXGJOSa`#(6D zdosmi#NHFdBl4V2u&?Fm%t?>h*FUh1uxG)0f&IF3dSN9ap zdIX8|wPPVAvrLdS{Rk;82cU82fG8E2!UTZWTbo-B`gTar{6EoCIWT4u=ppKX{{JA( z`3axrHz|p}MDIzzQq4s%Fy!T_W=2AlXoW-wP_#VyL=(%SHTqf5ct?VJDNo1Li^X7$ zpUg;6O(kty`LnNfHCa(n6S9*xz5hl!LNas~Dv6peS1c12CfO20Fwacv5Z=}6e*sUn z!t&@_lwCe*N-mL@ZLj!JIQvn)eFB!A-_&4JC6ObgzMpsN!w$hFLPE-uE7m0u z4gO-Fvf>w+3eA(l_)GR0JzT)fQY?Cj`A`lkx-`<#&V#H6DapWDDgu*OM^_;!@l}noGkG|2p?ZL%(HF{n)2-oNosWB(uG6?Iemt=~|xttM+)2kzwDPPB_=za#ec8M@OuKWxC?FRv}D z5t#|0$Yv|S%jcQ_-t&92{q5i3t;DsePTm{4%@WHx{z77M&8z|&F{H)S*IY~2Nvmrz z{vcL=v#&D}3B8f8YB^g+5BFN7R0#;eeFaiCB%6_c&_MC7>wA8gUh?*zSyP1lLQ2hS z3H#3+>_Ma!@v|Z#s5>e_*I*@QnPG1^+eG-(_)n$|>x~SQ+!B$^E{g{DnnsG2P#Z?@ z?)_7od^jR7zlbM6fCVi09P?Uik{94Yxqbnx#5`snwpGX*LksZhv`PwAq@Rj5`Uu`# zuW{-`v5mt?l%@L^beZDqad@;&_e6PEDq@jtn_LF3%5;a~@Yu&-8?q1_@{x34 z-CrK-VlkDmt6_)ksfl}Z3wVWCh??jj`Y5KWxa+WESg_$8QyQ&ewrxpCH0zotl8M7> z;gqAHp5)*uk-<=3x*67iUB0GQ6YlK;%?wFPA@349EEx=Dtr>PXw{UVoNS7ZI=IM}$ zEhb~3w1~cPoo-Z|X5Rv$hycc^9so-(Flsp1J#-|wRwdS8%f1zxkW#s5i62wkeG<1s zw){DS7`~P4oN_5y`TY87gaG?o9A2_%v~1z}*ZMYr1hZ}p`7JMr4&O?XXy#A%cAYXW|uBwN9CA_ zjZkM2kwNk5q69sG(H*ko41VI}uLX(1!rV}_yFkMeE&2}2nZaO4@-xi(>x1l$Ls%!l z(is$k&q=p}Dg{I&e$j`=R4!qW2PDM|I_ayDFc2-{87oY6tEblg?n@4!hrCc`{P64| zoPFlhzrGJR0eJN!DoNhf;r_B#M;;Mt^ay|pW6la|aZ2ZlOgzsqj9}!5LGk)X);G8C zu0AE>qgIY?`15psQ;0zR%Usr%k;2W2r|~#pzvJSBY20ZX z%eja*ng(fPw%Zkpn{$~{a4h4|-9MXq6hFp(gl!h{fSIpuYczU?hiXx;Y@DUu z_Wz)3iJzF6(4u(Eh$%Nu8fhKhbvT4*WFGp**C;{#Rh9@B(}k20Nf2LpfkwvaW1|1{ zHA=*x&(4jDg^V87m;}-xj#K{>RJg5d*1s}(QOT9#&?~wQs+Ss1pj4mqbJH&^hc2~)>7 zmW>=Ws!R)q#Rt;-qAgHGLQ}ZMl~6f5GZnt^B}5mv$g1Z2Szmo05qoG`4t6Ov4zhst zMXh_srYDDVR`EHphnc)$naM>>+018~m@_GII3)*4(#CJj(MCz0RjY5WE<>*D(7k)F zzC&)FJaW?Ln>h+97Mj6cC@;=M9e$CG?8&=N8?coh8p@DUzKg#4 zv34RAV&Y=Y%Mt9#pvZ)qM6X_yNkk9<@sgtD&~G`W!*LtU%o-Re1w~@VXs{Rd1*&7H z#0Gs^wb)-@LQPbQ$VPt<<2W{%1=oq(sB|}jN_gP1k@w= zYZFsc(Vw9v5IcA;{Of%ciPT#fhez;ZDiL5hJPr>@_A2>nm`~o#h__ZyNRd1vs0rWc z;j=it?3f2?Oj2nF*2%DH3Pr*)hRvvGfzZtwM(sAzQnvwpxrpZ1zSC{(=y1TwjV5`c)ei7Kkvanu+h$^{)a0H|G%T0FHM@`1^ zViZYQKHe|w_X1r7P2DQg|KNYbpJ{V|yY%QLYXsgSZ~_lSn8yytrp_&M|5Skn@F){| z&__T~;AF;1j>WAma%KmWFtwv1{B>|x%#HA;i%IK6oj1#B_ks`F&Z`p%)F-Oe^!#1!p*S91m*|hKFwnF~(lOqd7@Gg? zEFjCrpEAmonxB1hns zmz#~S9Ui>8S$4#i3EZ1Lu}KWVOWTrtHi+=QM|@yD%UUs(Ell>VbTba*ejtM%;49VGorb&>7YA&MU6F%Y}97CMF@Rt%Y?D%KoZ_<)W zj%$g{)+SOi_qeYssBG9IO&_+c*pvVkv zyyR%>o$82m{#%GJWheg4KJk@Qhrh+bZK5`aSCCXhN-1zszCfZR__DN*1e8dzv}lei z(!6cYr@2agvv8ZdO+L{ylzb9ldY_WsVo9jtoRQ8a&z(X(oj_o1ai3ou9FeBpY0=WT z-dPAm6W^h|OHS(qlJ#8VOtTefl81jz%ata1zpMolyP(nr{UdtEi?Rl?q%eB-AFYs8 zMZO=E2~DvBO+I#G>GxEp35+!O*+W|7$ix(?EvGt}Tv%p&lK&EvaiI&}kRSAmf5D|8 z;)h-FO%^7Y7PvX=MQ%0AGW=<+ZLG;`9@BVp-ir(m#AyL9Mm!Kl!5SZf%$>EFu^O1S z2L`6T?bPm_uTA$fmdNvGw0rK*XjB~vQqEd!=<#At9p?DQdBJ$I;H=znch?6B3pMts z?XY)6iCalF5;H$s%dH6+Qc1|lM^sYxoKzAD-mtAMFx;AvX5~4(n9I#xZEDqe6r4U+ zX22#3Z0LCgOy1!r+P-=S&4=ej2;6`$R&yUBVtxJvWG22ZBdo z`AV{q49z30Y1>G@gau+G;+tb2UfYaF@>%yLS2vGE`ZFouyip6@k^)V&5g+9zE*QQ8 z;Fp+XJBexTQfmO`NK5foHwRy1Odp66#)}0f6_9d?t?C;L$U{+tMCnmQYLS7}(s5E+ zTtf9PRPoows_?#gc!9sRNr{%>#>JtiE3+J-zl!L`J<J;UsS3tUx;vM!Sr03m+>~7+uWC=B$KO4MIwS)`h$G7r@CJZVzjry zuFL~=^bO3a4mBX90b`_~M#!|wF3QR>owEFwB26wWlG&N(pJRr_kj^g;*Q!#wGapJH z3P{3kDCnes@?!x>;2#AIE&$Z)YxMdfvHmb){hb14aCBTa!JI-+H5bk;asGN57(_`t zAaH`@lOiR~&*s7#WQ{r8sinVDslkmrN=kK2{ktw6fxy7?n)XeRC4#s-gOyOVrk1k7 z(<(Ggl7{OWS5sQa%B=7T2c-34On<3xXVC>Nq4lj3Xnn}Ync*+pKmA>(i7Ut@C}^vFS0zfWQ+$-`*<_Ch;o zs#dtXmP|1WL51JY9{3}*RD|7vu&2FndJ%7>;*%LHF%1>Bbq8>#C5!gtrI%TsN^-3Y z9q0ow)esvaUPDhx z>Lao=5|}Vmlx%1`hjj8+VMlPGi$9+R@9IQ@^&CVSoO3x}eUavG9A9K@n9>HDL-SZ$ zdT~B!a?-=u6xG?UM{wrBbktxW6NKQ*DKABj%zmQ%tQotg`4yF!sD)a%#jhJh9 z^9pZKoiZPcy%I+XPP-Q7^DB|3_LI5JpIz5qr)H7!z`47-oOqFjMKikHU)LWn8@t1w z-F1cO*1c59A9H*-tG=eBX;BX?P{8S^8Z6U$PzUeI2rOGq27^lg+MnzmM9IXZ>C;~9gAKQ-k-t$wku^z5S;oe8XyuG1 zChiYZC&?5O#jMC~?C%^!FjeWE`KvEXw@HmQqPm}I%oG@Y6>Z+%SY~QVwSU71nu$rg z?sOTxYMcCiH2T&iimL)!2DbyD=u2^<`-7|UmD1E-pC;Ii^^N@zPBrVNHf44yJCEOl zDnHO4DLS`^WJH|@@MT&vewgWbeYUwMKQXZtwo71pDsjoIb_Zx~1m zH2h(Dw%Um}1hi?NO2Pc>GW}?M9k3&1VUJzMpl+#wsXHjg67c#KHwa{+`$w90bC6JZ z#jk{K5jf6`%BDpwvX|#|-25c)Rk@bI9&V4pz=*0*${+KBfHdxEaUPR3#J7+sWbPa7 zzb3rfnfd;1Av|+>2;U#P9;0zfe%SZqRtFwmAl1vf)24nPuv-hLUc$&KC~p{`%`1s9 z_eX&UmBiZ9f(NCbXCb(uo>mzSNFwo@R}1N>goaeqNyD*c8y3No5a>I}iF9|7-$q+f ztWG2NTHlACDGKM)<`KHKoTHblEwR`88A=548}UK2IhUnk5Hnf)+}?zVQ}^cs() zT`BDuk5Co&j-?76kHziP3cw7~x-Uq{2MTK?$h%T;UFUTa!!K0us1&GW`cOyRR@g7Fh7wUm(U&R=KaNtFHXdZPO($Kd zRM6*Ia8L?l%Wd}Q7jn;53$B>pzPS7{`GV{Tw%{2lD82<-Z;KX$8Wb$1Kz%*_PSX7> zSNQ@dxUEw-_l^`}t=vWIhuRdh0bY#jKJ7HJ0z~jJ%44PM=cDg-LK`#yc#IyEgC~w?Y@Oe_5NgQ1d#D z?jrc!?B>)CX;Asdo9urE-;zuA!w-A#V_urVima)=)coCYg@~t{A5Cwj9WD=8gh}cu z6O98ft#4JRa85(Ql+DvZH{&iy;lZx3tcYEh;*XvRNbU39-DK^TxB6PJJ5=zpEpTF2 zG>tEGzgq7~`9d}x`o+3X!BVfl<3aRvzBqBEuwR1fD)OZ12>QA&QQyP6!yKnh&3A%Z zyoK%a2f)L0;$<_WKm;VO2OmfTDkb!^z{mf9x?kHv3=)iIfkziPhrHQvn?EdN0^x6} zlWJ3Qp55CM)`hA*d<&GwK^0TdOS}^yZJc>roRYmnN4g<@=~htR=>;Q0TC2`&@^x=O za$QH8Mx2XObH9LOAFQBjX438AFK`hYjG~Y6m^xyYdZlm9ghs}L2=Jsn$Yf~~n$4o% z>poBtQ&}k)0d?#PNX%CSaU-^l+1^*U!0mxqqsX5%W;TM9dX+E?(99)xxj&!nuV)ro z5P9ORLT=m6;oR)lRr+B|^ViK_JuaYY`w0lEe*HXr9Z3; zq5d)#`{vkMTn+d2m%1VG(64?;g}uIQkY`A<#}{R_0ISK{`&E_ zyG3Psm!!nV56t&xn=i4Fphj>v3=p!5`>V3ssWa0rSH*awWwq?Pi~V=7LLHk=*X4e& zsd0@=a0&RVRgJivsRrZP;U5cp-!)E56;`-_@gj#sgz0`QRflkEmauo( zb}hJiuBo`y?%?~FOqS@(fr86ODg0)E^BOA3+%=Fci!3O7{~gdiHc-qWku`;NSqSdd z0c=+XUFRe~3${zao7ag1uuV`mkudY(D_ct^$cc4nXN-aIY{0D zZR}PGG>1oEsPNoXpL`eiGlzOpL@{p{kUSnUe+(@{`!6ZzJxp+!hl+dk-GI{T!`e57 zN$XLO3V%c3^@a;7&H)8Ay$296$)ilka2OyFE)`yK52NtkaAvp6TLG0U6-?1IH;fRX zuCf~iey|k+wR?m#EX(!nGbzZwUdG1ttIaZh>Z&+~@saDrhH^u`5wM9KNo65PT2Yr6 z<9ixX+w_s)UAT2QsNang=?GQyv%oGJ6<$%#6@WGiC{)Rd0#X&4I$9`t9EescMAw}G zOZ+pdR^^GhmsF;Q@jnx?T)82Jb>va_^ado^qrm%pnW;*-)fnI&!&1%P?~)>M-5Al3 zwx_(_mlWL5H%e3O{31%kDnRNVn|5Ou|M*f0_9?FAU#h8ELJPW#4W~GTxK*4DLNQeD zegV;*C{ueJOSOjBVFXi+Mp3A5usX;E=0J5o&g15%%m-B=7+iE^loUM%nyRhWVC z6QzNnmYhd!e(2ahb^TDbL})Jg!-2 znH_FG>p$Y~n@kr%A<0`7D!A7cILSK`DmZTooaAZd7dR1NM$J%C>@Bphw`_2A?AC&i zl>HPcD7q!QQ9T}WAFNlnQ)W9t@T#{8zSEq2hF}(J&65@G)aR0oj?VWAck1)xMp+=I zv#aiO8)`KqhJzmWS2GtL^-mJ1@LW%3)Z_kshzN7N994z^&_CP%bzt~P^1 zfBoWD{ulkWuCCf>rv1oZe{>@*brq7 zP~fCAXl4mq_hwhj2QJP5C3H9hU)KR=#7pxz!78vTSJ zbg$e)kOtM;>QMK0WO)9$oh^#QRn@|!p~8U+q;mJse*!PA!M^aF1tKjRBP;&!ZNPPF zm2o%j&HOvWEY7mr3Yrh4l*|)R=Ds`lD%6$y?a~B^QhMwt3J?$SOGVgAAz5J|ybpo&MZT>rVQi{dDH-+7So~g%th$lblP8cXj0hA%}#RN!H zhewO+@iiCUDZwE*dS{ zNv&#?z}pVzZdm-?XaY~ok^e&AZmL9@d3Q_uoD_|Ifs^cJb!*i$2k%CO%idOr9h<}v zZ_j(6BN3hzwEl`9vLgqTFW(bBdVODX^y@AaS!1)V_^-SO>6?Cs^sX(q?q}7-WLvp3 zyz*1>C99TodC5l%$NG34d0e+l#>h4Dg_pSc*ODnS;jz>z=F?>&>8_UAFGHhv3|3~& za%3m;&0Q}`?R664&FbZ06_~fdFR6pA9l1h8&Fe4qstan|3Xve!GK%Nr~e~i79%a3eR{X>7#O!tk=qz$Sj+YaSdXRZyq z$aI>&nvRG=RmJSNUGU;hK+G#oZ81K*e??=%+DLQVeW+P=r7QaM*FoQPpK#Mnv>yc2 z`2O%=xbhA5!}s4W3#wDx&kLy6EcA1=HKHP&kPMrXz(JCCSpXg4;7i^F|LZj}gL1tY zaZ*4B??cOWd4L(6?}TLVTQopz(M=DCmUZy=1g-~-zO}$T10`s3-UdE>Ee)0(|3L32&`f$M1m0TR+4Np=(slhoK#6Y~v50J>g*lK)s*(!Mz_K@ZSO}rE%c{ zE(P9qILU7=dj#WGvnVQVmfVwi`VskF63Ylo)WQ9{f5gQWX;L2zV@(WKXFRVTv9_|v zTJ8V2E|O~VQ_Bx0@AkYdv`$FQ9R}I3m0Yty20;?mX#I;nrv3_#F`9A_PeFfwO!LP* zM)M_u-UE-}BN_Aw&5yp)=QE!RYJqpgSdmGQxzXRX^nN2odJh8QZ`>#Zt(6rtMZ3`s zYj-4|hB7(w3p`Gj3Roz)2^i$UhqPJE|Kd;l$<63Rk-c8V4|}~#o)oB4h9B0o>7A4E ze5Ee^`tb4a+UDNPa1}g3^S#@KK{I*}4LI^N;ch*DW{(KQ1WbasC*@j!gU46M zAe-EiN`f)@BR#o7jycvlDcyW8K&R#zsMi}a)AdsA6;FwBbtcM*z3_1BQ;vd|I^8~{ zvaD_xCh40HuY7CX$!N#Ff;ykSiABdVph@Jm998qjCcnhu^_JM#sQS?0d+(rOh|_`I zQ5&vld!ohdpH`Q#RySdVNLlU4el1z&y+zaqDU(`fev=b3|> z_~K;`j-Mi%d8fG3zkp%iZV|fd6BN|(2HYH%Zq!>oLU5tU;fMSbaOK0o^mJr8k7;&Yji&k8dH23G z->0g?0JOu$p@sY54JbQh2k{0pC(9eqoGecjpq5PbH~yxL-8b3pn{4-uO%EJW7C9y} z4O?PsY(TO(*ybap9IY3?)Z^LAxL3dQH;L3U%Rc7&Z{-%nA6%@IC$QSr-nXLz+J7q- z(uGrBAt^6@NB6xO;2uY6e-9|_5vKbMT5e1*XFnelD-P z;P0HyyCdm(=voB1E9Q3!1RThNxORwSU;}%hNG?fgn``KaY?UrK$11a>c z!V>P>@XWVyq`gICh8!r@zf|-20eTd=;jaB_eUO<@YdQA>yiTfwaG7CYu%Kd2j+yf> zQu^b|Tu0!7ShqgYs zJvr9g3F|q&IJ7hla2=nQe_+bZd_1*@sq-UxN=7p-Po=DspJr|%bGYod{`(^wE8Fkk zKLN5`#wJqgAN>UNv6VA2>;;Q;yI@NG&&;RInIx>-_?o{iFA>X+9%+|?my(@+xrif|H@eDZX@?~nU9Fn<{}O- zUi{S`V{S^yNHFd1=g?rSE#!X6lmt=j6(m2AeirqHex`R%xcPsWHt1c)i4LCLp?0#2 zXJ#{wf4+S~<+i1X=|Lq`egj)iLp!}GR4{6l9}^ET8}t}si-WKGA|ct_AHuKomWRKt zucgjS`#NUcTS6Tw$EJea@^?$Uiuvm;nH9i~{;dmBFG*~~p$BRN;M})aYce;pf!g)9 ze(z~C4VJ&>*#us)yu;C=cWFlZ!sYsI3TXdeTC#cM4=U0v|HXH-S-GasyU?uhr>x?4 zu$j=pG4FbXyJyh4PJc2K*ho=kX*Z5JzIj*dFE$KYrrQqfO;6#H%Q|@9<~{w6>;Sj$ zU6mtLhD)G|dHg-?70=(^qq50IkQc2d{(TR>)%(Er9ib7g<|YQrE$?gZ@=ezFJeH{W z7j)Dm@XPy3r_jWH0RC8k&$$d2MXwJ$c;@)TWb?Ve)m8A~2TETrCMCz>bP>t4YJ{im z%YX4Vo$WNK=a%G1+-YR*dOr}SUGv>s%y-%~-)ZE0M*|>rMQcY8KkgSyOS48GnoeuFpPF z>9I@@@jmn#``~sTV}G#5cyiqBIAiko$6~&QV9y2l;siv_f8uXUlpO6(*t9Mp@y1$Qym5_}9t zhI+)C=FwPBi$52la^9@l6=K)CRI7H$k9b%ve$Kql^E_@9*_Q9^m?TC+?+hM2t@^^> zn8+FBMx9V3u1UGhz#*)WZ4ys<kLxrt=#Gs4VpX8pbAnpB{qS6g=iLSma)b) zc}y!`l(L3r7avj>iqWCG*?5+3_kEI7vy7F3fAlPaVplV_dFgr%)YPMFUS@smZy=!z zsz?-yjDu*Gl5?OpdyS6or)+eg9Ts=oEVFx1SVPp_QfbO{#u-~aucJ27Y}Fj1XE}(c z0obZJh_Y^wX?-4MtoVk(&h@sq1P+?hInc~(trnRVT53Xtz-~n;NRPUSFuBO7ejRhS z0~X(?=*vH3s)25kY>8;hCb2Xev7>G6YZ+Tl@pGEy4XJQSRsbfG`{9N?#|?Xqr}w#d z>~Oppo9ldH#HMmZmU56NA&#^cbOMNy9%N=$4Ahs1NGA0fPVB2360fj#z!wbWs(ES~ zZVk)O^f%j{LCX;6NoKz{$-$Rp&BNDrmEzBBCT|_ZlCSmyYz(>oOl7Wea@$7e*!vVg zvpf-&fBl09HLID<(lHUB;Z}+=SNtd^B3aJ4{#isI!#w??Y?$q_Sn#-f8RG-Za_&MB*xmDn= z{w(ctUd-2DfE~-;mfhbk;y%F9&qbJIBD93unC6-)ftD5W%#tdB^qLHFIiI4*PNLVE zI<3mD>Kt=jT>hf4`f@zWlYW&YiN#g!zL*`+f#x#JlTF_*xI(`*6Te#R!{~#es&EGhRXUHNkCcRo9Adh>SG9NHhQ_YLERBaWr zQ%b+jOwTmOYEWgJ>fCZxKVMuLmmWv_?oWe|N*wp00tpcV+1zBAo4{@2gw~lqL@M({ z)EYY>Dd8Dqg=GY4o3j+FKj{yDl9@A^+1%p~f8)Bj)(i?$q6I?NN?UZ@PDzeI-l55#%lsMXm9x~p`6#=AH8ttl{-<~t3Q7%A?YQUsY;l}VkH3|MRbPxt zYr=8ncM&$s>_9qul>|PzXAMRbA4Qt4k86E}rsqv)_(`#6k%;?S>>JO;Ry9}G91#UmAu*8H&O07v@9Pv_k<+O~PNzE0Vy?A4 zOJ&fSo;=%l0ZDA=qlJkl{f(RFmNz`fY!i|{YYB$Yu&)mmp5(FRC_hZq9c9m71Ci#l zlYWA(m3xPfBiVn~pYk^|*{ATVT@qmY*`7w4v8VjC6DTYzu5veXXCP?OPWcneC#U@J zCi53|d6iE4>vAba=K=xAZb%B$GyP8c` zX3jHQqqFwFgLrbA=b4wLT97Gx|G$iG=&{*tL0YdzmvesRP%-vD*-)a(dw%jaA4G^V#cUnzz-Py3IEA81fKHa|8QFq6o7RecAPD~nB%sGFZs61=k znYC%C)0=XVyuDC-I(^hUz%QNSSrW0)q#83Z9jx2d*d0?{lXV{9_&J@X4nNPfDbM=v z!njY=E>%T41@XlU5RZXKu&Z+VjwM8WEL|@63(TFF;5~4`-*_Ogd!*Vhf@+kgjwOMh z9kV=VmgYHYl%7NKb92bDRJ;%PY@|7f4Vf<<%hbO})^f<2DN2>SJy^m4_An zY<+l(3$alYTOp~V{em`lD%^OZW(RNNLe0JF?;V~z_*7aPeGqgVqQ0KWgint=7BT-ChVI-NSnowRXD$qDS z&tASQ9S<|?Sxm0$qxe?B94WcQO<~&RQP^m)Be=Ztc~pR9#Op%6JUxoFW8$n?Vpa-A zs}l3h+Q%lXY2d2bp0&YwsaI+pjHR+jc*|(^IeV)F^_ZT`Wx}37Uy66wyxAPy#a0b8O31S=pwiAUR?38FRRexwTEK*5MHp{e zss`$VTwaJhn=G+fz-P8yN7}_M)s$#?2`1bRrkU7oNwih%Gku8ld$mCQs66XXGFN5? z8rs{wmsSth^t;8?k$_>BCEJ)qPYbwZZmt=4A5zmOhjk{g1_I!gQoOOkRLf{5UZ7#MQuY>viNFoH^uB&fpmEbYYodj5DRkG5I(5uKBzTI8Ii)XD z9^_kIcw3dM3EWjZoR48JzRF_=a$~Wn((?n!DFdP7Eh|I^l(7#HWWoB3moa*b5whFz zu-n$>1#r&iQk$Klo}u<}0c;HUyHz?n6w;Hj)AK0->GYJ-4#n~n0dmujSN@2CPS06I zZhH2w$qW?u+?oLmUyB}YYCfnL2r#Odl1cMo%>WwPp4x`7tH?U8RQP^rNj1w80u9si ztc4SfS2})$Bpq%UxFnTgKw*gk6k)4RfEXC9iI{SF0rw%tg7I9hc}Wr9%QJ2Pd;8Tk=uqdGdP#cU4p+0fHyX z=5(7ti>A&^N1_x@H8_7=UO9gqcV9hs)!ylB41_U})_5_?+65Yx4rQAcqJLqXdzYNPuSI>QoIj z#~G9~tIz&mZByev_5tluSxtni0GVz?U~~sbKp|cnRw(XvPf$b z>SetHjU%l`&aAsEjE7p8uM-Sgwq7)mlc-spm@`@FfOv>uoAjGt9S~Vsm+lR;e%<$S z;FU8}pF2jqdO0z;Z5mC^J*A8Jbl1$88(O5xk&E?%chPhb`F zVrLoC+(3lcqHu1|D!gVF;14~-0e5n3X_Ra1ZCwKLbiSx_plx$fI6KczzP-065YP6d zk!7?M(*6Q_b7p#~dHolNE9(Aj-rbe2uC7}~qB_2eZqa7}@6}b_ zc^uF<%g1~)Kf7Ldcb9a7#+*mlgFH}AyTy5uh{ccHs7{Yd4qV_BeYN_5+JsTj0U}Do zm0)bW6$_-eet;kv>|XhZB)|eM{w;w(*!2T-fotWdRh+Ieb-M-XaH)}C#dcq7E^jH^j&Z8FsVDR^8;fpq zV*6H4_{O6SBI7l7dW{NFOp9JH;@DP9o3mOFn$q`4!Lo{sz{nolozmv#J)aOhbsV~PFCqlCsFEACb78+lh@+Oed!8HJ<7~#E~`LDpY5Xn zm0rdC);u7${M;<`+bj{565jrA7y_ z#H2eIZW+zkwd;iOyjnf_m+#M;{b^*`3Db0d?GM{O$9yxub){!cnXYvB33uF4KYF10 zI-{5EU~5T$Jk_ks__z>M$2S>la{9xuAHWocB(J)w*!6 zC~yn6#8)!cUq^Rz;XaEwRLYn=*IC9Ou7za;{E|UB#)NZJcxa3t6}XJ?;6V5o#|%as z-rt|#E4Oq@FPiC*q+Mj3k1OAcdzM314o^wApsRtwfu~%_Z3Iy5bzTBwWyIFDDu{f?maRZ6yL767(;JDifm2 zGp&@HPSEFlDZ!b^5I~?|V(612iQvTiCIU^C1d0xc{(ZwlT3UNHxejTi;ea%($FbJo z0(8@Gw3y}#?A9hw*L*Qt=4mdgporW0~sg!F=Z-%Xc2KeCHwK zYMWKT3$G6}h_p+TSwDhxUBxo-dKx8~qbBJ#%2i~J_fG0oDw4IoMa0TZxUM7Zgo`vg zv8PIf>p6iBEu;^P+LxJi>7yuM))6pH3qsPhn1Tf5E0>})3biIL!oe|8@(#F#{_jyV zcW4KXt(ntN$b&}9@XaO~hTi+z)4}7d6!NfC9TrVG1~P5(5MB9;JHqFBH_#Mi`z!MA z-1|7$AU}0wQ}NP3{bmK$RaDCM0yT~-+npyY-@AurMvV^SH>k>?zh{vaxN}c3(+N{U zvRsgbYv*Pxb?&$ks;5|tDP1c~+Z)4#Sv&U3jWn>VF_khF5R=&|IK^5x7LKT{E>&<^ zuTm_81zd3}uizB^?l>rwRd5224xMtE2IB%vrJL5RB|ofe@uOTf#e*f?j2Q34 ztDwB|sz5HKmF`Hi3EzzWpDuTtV7pw!RJ$T{DOfT#1G_@8So2;hk zuTwbd8Dx4*2{bU0B*q-+9^SR#@hPb#d8yUSpdJD5QMrDt`6~1%Z&wdbCkni|UO7`a z=c2jSMRy;qz}|E#?JHIn7u`(bskB<{j{~yZB!)mLSbd0I5xHtLYZtp#awDfB~Mxt%Xm{qA6PV@&Ks> zlUw1HX1mJkU9E7h@|y(CF-WAjN8y+}ivN|sHU8VbSId?GlUw1vFQnEnL#~lIg|#i9 z=+J?m$-X5(au?FjdAo$btUxc!-vW29s=zy8G^^*Uh*zJBk9Og;;dc70xwQYdf>QS|(w-U(746dUug^2MbNB z$&}o9Wd*v^?KDQ8s1Fi}^25zS z8=G~Ixp4t(ShkXLxZ=TK}@^M*Xl@8ub{4!?NMhH#tZY;cm4A z_}`%7NZ}2G!ZrwO&4eXDsdu5GED6CELh{awi$&6(K{WAI_wr4?;8c?RA-8*cMoLaMhh!s z?$c(w}JYdqIF2?IR!?#}TF+?#;{@6CWYa1Vx}UZ(D~8R~tO@<;W2p*3~P zwxu|3LldL-gLJR{GI(8fVk}jVyvS@iMzo`-d&NDo41z1hIIXL&5zB$?x;?#e$&L1) zg2a77_hW(YImX++8>OI>2+76?fP153h9a-u&GxR5DFZ3~}5i=GD9=j>OKs@RlolHagUGPLym1!J`cMW^*e z-wPwsU(1My!AQ_l5Rw!ViB_9d!m}vaGkdSnY*8#v+Ooe&Fu$5b`gl=zG(D=iW?R&hG(23Y5S>VFOo!RPz>r>>NHRm7 zAe*U-Y{=v*;^Olw^p%Mr6rB)u=AKwi)3-*ZRIf-wCdOxy zg*qg2Z+x1ORvEHvnu%gT0rOAj)ejkaIV4oKQ=_n)amRSelZ66v?R^*`Y(^VJ0TNvE z(tTkTkM_95{q&=(`C;xyBy^izagtcA&ZArrso1+2r`XUrtPXimXA`89d&JA`m$x|E5UpFpr65+yf9- zZJ#&=;-$5|Ed~1*p>c1+vSb>eOKrE-s@ZvRO(37Q3Wd%{EObU9hx#7#?CXU=X4zV_ zh`5nWg$H4qZZ`|9YpZm9DCCl&x80-~!WuCo<+#@l1IBEhDihcn%~bQ`L!hbSv-UJ; zri2IA@1NP0jJmiYBibyR7N|pk9cH|MNrbyQZIL;6RpdHNiQuTV*0AZ8_bRmnWmyk- zwRb-73X}_}X0jAu@I;$}8G+hTuSaU%dK%xpCClepOjrsKTj5)@9>1x$wqF-$ik;(v z%=5!?%=CO1ujbm7X$h<5q*XPuZV7lnujPC5+{5&qP`cI4Z?|B{(;;s_h9z;W`q*c+ zs+vBx+Aln1F#Qplf|FDhM^E9IiU&Z>`ju5C<2G6Kox`)+qm0bLt+l)rMQeQiQNG95 z>Dj~z%h&)6LpRC{nJJu-rA7;uNP(JN?`eS~N0x$`dOJ+lPZves?0ziJxq3*U%I$2K zR76tO>;hIk?8W(T`Pe%NonCgW8M{#`EpvqR=0@1W>;Ed|+-!AHqW)iBz!6rn$LV45 zQUrSBoHFxk_2Up>enpy3=C}=(c4^Yf+?hWnKEjq*p4O<>f^kovim{xk<#6nRVrofd zF|%%gX7F(n>q~G<#5`SXF#Pqq_D|Bb;(4-CNq}vIJ^3X1>cG4*ElPNbZ<%}Clbo+i zc60Bxrvl_3<4J>ef?H_MW2>4!p9)+P7FdPo|EN$|vajC6AG>7R*VN|uP5-lGH+dSQ zvTR)Wv}L1=z2o5dr`bGxvlw5WzW%+iK-On(!lf7uL#u4O@s2WV?0pHOcHg1BW^1Lr zeuuUR2g$1~*`1VwlGlkWVxAjK(XzJCu=NYeF!6qYO_;}U#V?Y2LY%C;l>$8lx^+<* zc8-?<*eRBg$4NrVmTcyPmRab0XI!CHy;bsDAU}+i9U3`SZrTPJ%Sw9&X{v26uk+_@ z7q*qz=KiK2c`luGXBmcF^$hgXb+h(P5wFk+wUYwe?BUa{!Lxz%k~eBqj?pCd9=~$A z?NF9qOP>{z5-8}~yUJ+uxzBLj?!Y2Mx#QiUCLJH5Ll&ax@?4-ZH(CqJy%#k@mhwVC z4y=j0OsIakC(B-uX8?Zmd>9M#e7F4$5%Mx~^2r@`>Urm-ikA2SXxjUOOI`1^U={`R zKFV}mCUDt}EBsgB@p+P`HzS8EcH~nfQ(eB2%AV&<9nTCDQ<;VEpMxs)%QA!K?}xGpuDZHstj*G2cBSg%bN{Un(~&cnsaYY z@~j2@zRgYu&&kh-juO)h?wX+wr+X){f&ddUuft8OZp1HEIT7@V4!w)?s1UX(DZ}4} zuOS}~mx#6Q_{-MM-U~C84TrdYyhg>mwXSTs7~HcI%3Lkw7#l?Zy2=!}_prS8*9mR5 z?F{707&+fvku&d#+S9yJg6?G*c3iT=(cMGHk_o*V5J68$=??H1tR%rBL_mcXIil> zqEA70F|NmQ0Wmy%;hVyS7uz9qe+jLQu#yyg%QQtg?_5|&ke-oIznWN(**3(DU-NQ( z=5KExVb5>)j1}&-*`PKT65{rtE?8gLaXgWkfH7rGp5sQD1@}ti6vdS>+R2cr#Y?U9 z%&<}v{CO`_lT_Dvt{WcCPyw5<2j^O8&KHkeD~b^__lKst{6Sb2Tt;=s0I}fx_?!)r z6d68cAvw+pVtO=a7$E=qKKQ_00laenj-~XQ$X4-sK89c}d}<0GZc3unHxSjM0az7% z12IKLX}MMf!CJi!!|U4bpeaCPOulPuBJD+ZBUhwP{X-a(JB6+%(CY;((qKr&E`)^? zei+15|7t{tT(zu)ZmY&`0kFV6M+N3I#FE2m>FO+UTe|xfL4y2jIc`PaluWK&0=BFj zo7?a#EG#8nyY5FY6!>%W7B=jX8@!JWs!!P{ISx)q?*&Vs^$$KGbOr5xjx+g-bhk?T6jZylcm6tqF z%oN!t`9cw1?dFH7nduN>nXv><1e@#j@Fe=g>w09TsL_eGr!e*{*X?%Ec%_@*n{o=m zfaTF9F3)a65?hh1TOX@59*X#W&k6@1~@DlykgEF8o;q1GC z4dS{rFx1!we|f!>fp9od!Hn||6dXU(@Q2V6G;p{@si450D44g>@DUq+(3@B;==GR=E|`58SYW+iS1me`J6nAfqi`oZ+h6E^-b9#eRkvzEz;(a;3w2r4EVdSei#vaXdcn?I zgHd29nq0H^{t+Sm6Qd5+1sXw0_reHp+V~SoQf$8&R{n1kL~R3hlHv7ZP|n{N1ckWx z!ilL24lzH!gI}tr8adaoxO^P?-!`pH`OEIt(HNtz<8}-B!o9WiC9XXRO|oE1*-?vb znAlQwl;_R7*cx;bZM$RZ>P-w3cON{(fF0MIT@SD%F?&HyCekWAL@iE$JZUds zjg%4(RZzj>z4)BZIDnj-M}TzLXZ<=L2Zv*Rzv5=ik$qSqxT%GEAebN4vc3r?Z43Su)|Yj06qQSjf-nGPI=7!>obfC(<$%A2c}j+ zLA;m@)!}i@c>czmJYL}22S+e;K8GSg?fC+=+U8n8rwFuW4$fHi=Z2O+RW*?sFPV0C zzYI-s9sJ??+6{Q*`X9w|@<|&ty7N!$@hV=Rm!V?dRso2T1-IF7!m#R z*<5ksJc!%*YHKi}+iEjo-bU#O5>sm2h z0C7gNbLU7VQr+HOwp3C5cdCZtBm5OEo_N{9WFpKJziWZP1q%{zIWgc5)a5JLRQG_l zEm~y%p%B5f5`FMFEpN^Qc-bHP5gNrK;IcVX#^=N>&SUA#W*(lTBkEwpXKX!>c@epC z{TyG^kNy)AV?j-@oI(JN{S$-W%$hWaZUo}jWB>b;223d?Q8i2)D}?%VWc$GdY8CHL zF}O-$eDp~+sQJhR9HG-uAHhp-;FKgleTyMg-(mpCOK(L{UmLQpBU6W>Oj{9KdD9<> zBe1XGzv2jI;}SC%^b2>|`wHx)HK~x|qc5>lAmfQ}11t zP4NPSiRML70K3pz?7GbQUrj)4qXPcoPGxiy2O|h94v!X(pj0u?9(OeHE>!MJRjL}T z`2x=>zPdtm5sM>I{^EHtw8t51yItiGfbY5BLqA<`ToqumNEkojhdw%pK+l|NQE+Dd z#TF+e&7i_me^n@!{3V-H{e0)IoAZYOg#`q~@)v~zbip81p!(@&7F>9Mx!k%&Glevh zpPdgtM|{r~w}H7m)ltB1q`c>A!kblrB8hbuV4QP7%ys@EPK^NR$zsHj$06Qg+VxPp zFA^uY1W`gk7#e@^M1Da&ADZRbd9a*2++YTaSHrCmtSe8biG?`|dkam`j*`AuM5Ua_ zs?uXjrpiq&rTsUR77KyYsoXd^1SgXS?3sI$$A@SNE-gME;+enoxy1z#=v=TVL^s-3 z6{y~#LebuU!+{Plw>HLd`4+8F9LyvBEaNihmpiKW54VTle=e9m35Ea{tW^bS1gApL zQSN)dP}psvMm%IMzeuy8fOAR>{SWrTnA_YDLXWt;WoGH!+uV^R;vhqR*7^YamElqNj~R%gi~O~GC5AQ4V7n(rR>qKOnq zXJbV7d%S#f)s&W?tOG;hY*)E2AfwLRqh2_dH&aOKl2vX9}uSFDJKZEH$oM7iHwKb z9yAaa+@=CPAKfAgU@CDz&H6A6(kCN7Sj;1CiaZ2p%3&S{B6X2GWycR0k|LS}+6D(g z^r<|+$QmRAYK1MtR=y$%l&2CuWXKqPNY@2^$Z!p$BU0boHEejH8-MGn>LR50JrJgQnnwZl*Ar5RS_*B800XCe}HB7rRw=yOtmu{gA)XXM4c61FH2{et(Ln)OP&g^|uHZ!1_RJ~0-j z3AhndF;&bjZ41{H5nky*og8?*eel@2JVO<|+8dG5y+kzk^eqewDWwY)a3)oZ&lzuo zp;y&|kLlGCy-L_{X9g3LG=v|@>%X~-%@sk4EK;IFhAmknmBP>nCxHODN4z7u73HgN zc?D?{J{WW!^z!2g-h{gG+GQ0a|RCrt*m$E%<*wiO*3I)5k zSr!xP>w*3_hZNPSQx1dTlndVm*x>guKVL-!N7^D=cc6_0s$^OpjtJu|$=xzGM0Ws1 zn!S|00#B}FFZ@vUN@fL{-8{?(*eN<@z(I1eybIAXz|7pQ0MVTP%-q;A0{D#slMwwI zV*)2DxM4b@7GOAnRIVK#Pn+6caKSefQ90@_xK^?}ZPLVJxJMnb!nFyr#iDYNN+AJaZhdSu3~wr>h37AN#G>`V-n7in zFAUmEAa>o}MqL-Yd>r6-OjpJwa@FYs${heF!VVvsG!z;BD$eF>k5%D#z^PsZmB&qZ z#oI~+DuTyY*l zvNph~j(~YBUKFy?bL@Jmd#H5$Rb1z4Ul{Wu8=AkWc^fgldkfp--j+ZCd?}I$3E9u2 zJ6AMtS~ge!^U)G=@!&}VoDzItE8~R(@iY-}Fv%jLxQAUEaR%>B8k3h}^e!32)pm}9 za;sB}858a=hB=cl=vBpNeZYncnnxghOe@UKMqVC05#JQF`K2GpJz_zw{3*e1GmO}W zVSlEe0c5o)Ac}f`(i96i#5<{g^X6%{KT)7Y>$+65Q8vJe>9EQ)270;D#hTpqNGfn= zO@`mAZ1a8#=v4W|@I$g6en@UG3l`NdOSKY(q~aT?Y&>OI5UDC5-wx-E%|QwU-XA=yNm3+fiRBS0LIq@B}G0^!24-|$U25Py&Fshc#bkKaMtSy9BQCR;VG4_LAK zLEhqW6fnyENp5Kq71W7FWn`&SO#EOZ=mhzPK{{Hhk7H$iqbfXV{4|F7}waH6v9OIE9)f#kOF)WP4G`1 z!FP;cNP%j_X4R&Eb$E%VNp6<}6}Yguhzj@}>Q<$I6BkO0rK5mTI`1k)IMH|=K=6{K zt$59ziL?)sOOvEDQOf?Q=cTPG=9>(B*|>$_CAya(jiFHLj>OJ0Wy zEp52qie#GZQ^U)8M{B_}UHmS3BZ>$>6`qJoOpBTyIpl#p4`R@JZ;bWodyri&y5MR} zTfuZewm&~g!|f-=7KnOFY-)viSwmqaU94m)8Hl|kVcyjfxF2t+r;9PIsov`lB!G^! z6%WAkEqUq*&Xo^LNa+nEgo*dxhqtat9H@tm;&=>kJ>iVyYpki)TqBi^#;_*8SSsD8kDl>kj=-nO~y>N(8UR-IfNF@-} z*f_K-pzy~@nz@TX7s%Yu0gK~C+qh)!KMBIcjbg&Z*p8^pw+KZF$pGxyxq*K>q5)(d z@f7(|wID@7Wzi)Sm}23=_4X2r%=;Ho=Xfef9g^2vz=;`HxYVeugbTwxt^i#NE0ffK zykXFd4={$JRkUycER3F>j1mK@aFcMtF>HBfAmLIKTRCRJ`CV*bu1pl|KCsnu0-4%R zpc3d4MEMD@GgVY26Xly!CG+GTuBvnZcXi`K_<89PWu0mydSH0SAvEuTA+)a#=hKpE z7PN$kpSoZU+j=2Qc|diN5)zMi1e{a@6a7zJt=rT1M3FDVpeF<7?*KxiUQl`RMbt-m zX?es)Xx?o-#qEzUlsvMkRX0?N>V$hYL(|9-z~)$v+aoPFT9kX+O1I^^(@Udyn z49=yqFdAu*Fp5SeF56hBe*~jx>%Hq%SuUby&xk+Zj=f}PS)2mj0mGa12YgpkM!uF0Tl?et3hDek_B&kftpTXV=$n;J z=!=D8kP9Xbuz82ILFQ+z_foXpOOcvDR2gJThpm2h0QA7t4{R0ap&_mJlwGr9U|w0V zZc#*DZ2dUMhD6HS;s0=Rj?MGgjR$5U($C$vz~#UCk=#i+qR#KRVf*SPBNme{QW4_=~kOXex~1h}B>5Z>yl zocQ1*?f%ed?2!pu%5G73n01Rq4m=1^nLJ*KP?bGiOdM)K3-^+-7}Q|~YO=Y<$>Q^1 zgXS8zmI)BLqz$nc;n{#rL82r7g<;gf1h;|4hOi;!C%^NR|ILjxhYe< z!8=KLsfh95ec{YhFr3PIs?1btM&v~lyefGSCBDMg^B`(hY2;GL`Wtrf(YB=V;F{)P zbRUVSCuU-vNf3byIzb@36Q>-g46F7v6FlSOoE=NVtC8ZfOqeJNsvd4K|hZM4*b#}UCwn-(uLQx^cdL9)jKLF!d0h^ z!Pjd}K@BhO2&T~MEnX6wIl$J5HrN_vUB~MBLpq_pIf`8yz{wZJU=w&hXFv`_xGovqOA{u7t=rW)AgYV`+ zDdx6CvND(XOa%e#N0GB<9}!e=+(cUpj*AdvsfbCXzCI}%hDb$yJLfJ7_w zWEC8u_bDMKGrJ5h5-XslP$eF3m>oxrc7V9yzj{VqegQa;n)y>Dd}{ zFZxVNra1=^DyzK zmxxZ9|2Zj0h4gUIVm=Bk5^f9k2SF*^riw|qa31~KB&?tq)Sm{ga2qa$uXlurTwjFV z{L!C;jae}DZRnxe14u7Z=p~Mp9OBt`7z!uyTsuIo5Epb_fP&zGY9V?rMcu;-FcRzv zJjDo@Qp|x|)wvK=Cj}ym@6JG2jT{9}ZO>b1qkCWtzOz-QRZzBy2wY@6?!d!SoY@XZ z`~T6$9T4jzoy4$37G!c)R~DfwcVsqR43G<%Ty4{0SaAn>M@IZF*Z4!1*hi<|5mh7}_i~_iC?^5DZuv&rZPVukdztt{s04e0h?EQA#D(IHktx6_?zITh zH=PKb#g}5De^0z{Z~6ac#X<@9(kgP{p5g_NOF6h0FPsZ5GSXq({7*~B3ol(uqT)(h zX@3~goWhQl4#pPl^hJ&g4+HnWPGWq2w-OWizt*krs{d=qaSr#}dv%D`Rr0iRj zM4lkZ0!)NYWbP^)XBJwHolce2Bp^7JLFZtfu{tl~6kUTsxHHb@1j@S#(24)YDx|H| ztAHF8xa)|lv-rktgap$n$b&5xw(-{CID3e{@=PX@QX_VJZz+-Vs^&-J!axOKl|y)6>5D^Z@SW#;@~3l@LWvXz(l-4)WMZ6$X8kQeDm z8{RA{%1`z<^C4I#E1hDY>n1j9i2A&0ySG8d~iTh9`C6fs*cVfW4CI0CuM4X*Zhi;Q^@ zorXiTkW-Ms?YClX>|8xKoKT~eO6;S8*e}UE;oG8wu7sZm5#(W=^CcS<*m`p-vwy;j z&n4hq0lQg!v5{k+Di``}gRXd4Fvwr@8bR6)yBLPo+J;e{9bqeL>2>Bd)@Yl5vekn> zI#E4SgCAPnI{ADnQ@q>;%VGnzp`cM28R-z8Y{&2-Mp`xMx$R)xuL)#|lv+RAV#MQ- zG+9JB$e}Fz8AGWw8A0?NzP4f~Xa`#SWT=~*cysNf48V3ECvDO8d@e3NcGuFBm1%5^Ut;aFfXkFLyS5V9cI5XHg zj(sFB|EO8;MT)5Xo2{EAFql)Z&mB+1qE`dbVCNTz!{cpgu?f^a9aoW=^Yk|?N}mbV zMd1YO9BY5!V~XFOpk3Y6Bd*JmTS`iA9So#Xuw$d8^=zJFJCHb=??+Vvc7&oOsub+E z_vT%bxRwZka_6Fb`+z2Q@h#%_1J-adO_V&({&!(|&fbsdu+e^@J)&uLPR7_>rCtX} zc@#t9+~QM+XUxx#hdn}!oF|GD~ z2eD+oO;wwHu8M@~;iA$sg;)aln7P))>;pEW5yz8SO2;Ls7ij=dW{FP14u~{M#EL`O zevg^XD}qQ`?kVyxJ9v_$)nnQ(cy_W^Bu>R}jrn7E2QU5u=Z<==CiaL0<=n=?BfyM1 z8x+ZPLpfJt(~WKMK7#f{CSo}AdQ=+TvHV@YZYPI1e{d}q?c&Ko$@2_~Z-*WK#B!kJ zRo{RTNft1C=}}ZgIKP*e+bLYSV;LTJ4CBaM>nJFOeM^FZ+zDJT_!vG&qo}x>TtMQI z3$9T?ZdK@lW;0kcg8H~1{Wx~dLvw8<5Ga_WvI5|TlxKMJ+?E8d>e}OQd?e4b?8cFD zxn})nNLvD$;~m}+XWzcFtf1>B&~e{c*4d_?1c(EC{4OIS-_2PRN@b383zhO&V58aA zxj9@WQj$IgOj757BJiyB#0W`QIH2*#DWFN}=p^+x&3mWwF7v_D=+Awblg`Lx#v7mi z*geI>6+~MU^}-mNcLpDD&cK6nX?qn1FB=!c1w$Ps%p)O1w>ucNj`FI{nn%;8a1Y|g z>u1rr*L= zv$pcERFc%Oo;dLb_P!R%=jb8C2ow@qzOxn2@5FTQc8*>A`#bnFeE>)%VgZS4JeDU1 z&?f_@)4VhMdI5;i9N4A7xHIw30t+#S`Q5SZyfJ)#p@n`SV>6ya70=0!5b*sAnL!n< zd|Vj@@}0NY5h9W#AF-hyDnukn1|_?uppp;pxyYD5T}vxHSmNfNd6%~Rg*TRV?*+NE z%D>8(PPm9_HI}dz)dFNT!LkNo^;a(;^N7xjxU$zJ6g0VsJ+SS2OqGr}7|!q2q~$=4 z4*QUbIi57O4|C@|He4M*9fQN27kDMC!)pNP%3zLB~L^%&W&qmYA0YW z#%caHs+C>5wf_E(a$zd%JQm%8Y6gO36tt^?_JR#6uwBjY|EGad4_ zW4q)c@aNYdOcIf5P%)jTSxg`Dai;+j;YQ&*bn$B-*iBCQ?S|&0nSfh3377E{Cl$cn z$<@)!o0t%`K*)AUaFZPJ-@@E+bD)4Yxz218ENvZ2MO=^I!JMYLi`KC;(fFiP z>|#wRTrde*k9NspM0G20CIB{5l2jx(&LWlNnxrGMl2pb6(cm9j5}c+<@`TMrEGcy3 z(kYDFn5`17>~U)*2Htk(Kur4f8@{hrckrFd_{YG)#V>bIZQBN`NGX4pstttau-rx_ z7D*W4;v15oV26TYDhk-s&uzrlz)i}3H`;LF5AlQy`uHBIW^N*ov{u5!Ndo=KAlUg_ ztNMK#-6D^Cz@eeD?t@Try>TEh`$v-Qq?axQAq8HM2T+tqrXDH^Zbplw&KW-K0VdFM zGf|dV_Z7jAZq`$r-^`SNjR;rn`jA$f-p;7EMXmVJ0K*}Me+!aYwuRJ$ZnyFyRAnl& zZzTknjW3{r9WQWfoxPRy4=^J~_%Aj7hv6x1Z$;yD2Ey>q37+v28YeU`=;FW9K2kx` z2|7Ky*!GxZRL#e>V8m!dmcuz%$KtptObZ>5;FQLaOD>2>vs5w_ZnpIk^yIEf*FJGu zZmt&g6xE(=R}zpBFp@wxc$WTt27NaNINAF%YEjrFfB61?s1?5hxMnkpVZRWJ?+|~t z1G6^QrQ$Q5qEoxMbZT}n@0qQ-Wp9vC64U!>x!qgz-bwq2SV(kkn9u)C>?F=Iao^@S zI;%7ioK<@lEi4&(auig+_SN!TB>pLh1s7C&fdXiDPZ7GC7?*PYae<(MLA!Y_dIet- zY*=R;5#QJi#;5xdT=%1w)CdKf?f4gQ_HBM4U5a}>vUDBgN^e&mN_P7%zyPx2NO;v( z_)4B5{i-Z;M(iSj^NGWhUunkX?25fcfegd?m4%ENR{$rnWWnK7vDM=GYg;GR-5Mx6 z-pgECM6NYdxW>IKjUUz;d>z=FU4HdQ1#R6p9($|4NP8}jLGwF}tlPOXbK~=R6Lt2;xmIq~~c^PyUeN$3@G1S!R6 z1ShQ{*wqH{Z>LWZox{H=2U^Gv)$UEivEtjONE?_l`-}=ET!P?Pdy4o6dw8DN1%l7Z z0tp$X$+*xnuI~@{(9^W!y6QRt-5`*O1V;cs&CkdoFq?#n5dlz-lucLcKEtz;V+$9z z0}L;OSvXY&cl?l+sK^R7C|IX)pixrHIt#)h69uCS7aole;LpkIe9o~P)oqm}9gJ8G zPf_#$_Q`|J*`oER!o@TyWF7G5IhU*m6R!x);r?&`PIHyIHC$X74O`)Vy39jkm_8MR zKH(~+W8UTAp;Znc1pPs5qBN@ypZW1h?+-T0BUsxhEg|}$&Rei;qN5m-%$=fr22RsI z3MwGp(S)XCcs2bK; zVuV5YBQTsHe?W-5;<}uqfu`Rx!tf1F)~9O8`cw@W(S>iM@lvLfqlzV?tmj-4@t0f! zZvI&mn#Tr+_*Y|~b2LWrJ76xP9FE2so(~K17j>=^{^*V*wH@t=2n@du5LWZUb)s@| zR1>^)an#?Qg^O**4YZ@{d*F1iQc0tRA)}mp@lLurP{QNvOq1eVabPfOHT=pqZxH9w zE|;5Z9D|W!my2vJU_b_KA`qLd+ixl!BW&Z0B;QDwcrmv~cxil(ErH4$**@hKsb9Y0 zPGkL-3Lf2ZLqWT@3<~ldQqr*83BpLsm{96t3_J|vxAsq#7oT11BC<0gtr@9btNuf~o-D(5||K93yMkzmbH92JxN%A#`nk|A<`dDhSczKM0-4Mf~kZz`@ zf4IeoG^RY%_OLUNUSjM+GC#kc02~*nyhOW4%9LZ?-CF?- z%{__^etQIznFN(k5%urB#OlTVYlY7yxJq~e<^C@j#_@EcpN8yN35D(31ONFSGkKGT zp9(&qg07FPROsV6_KJ)(J`p`KY~{tRSd4~GOOn+ASHn1q`NnPi9EY~tNv(7|mc=EQ zx!RO?R4eiycS)%YXc*54_PK=VrT#Dh-(LPt?&np#BMGR-vFc5q*-De;FC~KIHNA)= zgM3ThCW4`hKIdL^i-nV5I1YRVSF8J@z(s`t=U}V*9YFlZ-_MCUH5G12q6tx6A-sNs zfSwoZxRb4giy$WkzT+A;8(UsjN%0FO#!bh$BIc!aL9aRWf{uOZTDWkrU<4v9v7n}q z4i{UKsc8;^z>^9(2;zQ)5R(eS#ao0o|tOrw76M9 z@YoEPchUI`ynLc%j$bvvvCy7ke13yY0Q742r-J+Wac|VDTZ@u&^E(Ee3K)o`)NMDc zj;g;Dpev@>GV=H~5C}K$@iiT%(a0ie00be1Gl+r)WRDhNqX^D2$=j3QntUD*e8(ar zPW;r2V7_QIl+j{&hj>rVxErpP1!eT`gY_J)qs9+4Co zM{U||2nZb%l`NLl206ievUp^`X{8Q8dgG$r|h>!0&7dA+=LLqa(gu38sACKVBoDboxI#gJZ4VU3~OOZ`d z5k)o(?^h3v-R_S7{qKrk(ae4?5WHYf>rm>y15mG`c=dpnkUqD(clS$OgJQZ;R17xW zUo%{<*dmaJGIG1D^^V1iXr@OV#K`(+d3!OYJGms{E`k1B0_(n_AJ0Qg{=Ei3(NsT- zi|CQRj!wcUOXNLhTMvJ#3VLLC*@kF>HBAqOgB}?^t)Wp|obcC7!myWSU1%jQQ6~Vy zQ%cn#x;8?eYvQ3bmIM%CgZ?t!BOe{**=E&LEKt!OH+KIUuou(c0C#vFtN}al+Rk&( z5dv;G@CP-MV8_)9BFy3{iG+1&VnmA{g0NQRn&dXYI2^&4yQT#n*5}MAy&D^?Q-FW< zoG^ZFx(%O=YGy=C_d~TwHlt)vij4AcnQ|!z z21LkKkgVLMIlf@Zk1~uHFBG!u-P+tJE&3SDBMN)5EztcR2EWFk*<%L5INr8_-O2(5 zTB6mpcE&y;fOwR>TB0s5Rg?of#u1ZTaGDBOtBrA3X`$M?;JtHcA;D50J#bhFBL92% z2n69JGQ;o@2`X;vV}e7!xfWEMA`m~$85<6L;G&VVR=^v@9ZFPu-wI-9Z@5v$UnRkI z;Y{TI0mC*rf}552u-Gzv-!)?MrHYO38nuaC<&m1N2y1Ob*wtN{JV~?@QV`z5X-cl3 z5)()O!3g)3Ud=4pJhdO+$2{E0B)Sd0&O;{S+E6tj6GyZgnLI{8&R2kc#c)%`b!ZDT z@Jpoky5qF_Mzj$k_O(UB;l+)zK`HVa%QdPLWS3<6an+ugiP}s=tBMm5$&)SdJQI{2 zLj=R;^(1?<+F@|r8HQb^T(YwS<51c&F*IOvV71zVUu%^B%#@B|MSE0cO}V-R5sQ{g zYZHiv$a=TEMQ|;de(XTJ(KI4dWWPmJN1BqcxpNWDZ&;MwK!GWleE86Y*}rrLBNeBs zpLQ@RBMvD=J&1=NdQJ6%c*{G&Amq^82PM(BmLwvg6UNHQv12Jxj$|`)-=nC2ZRTG} zk<5fCFAE+}LFv*!8E;;>a@!Ah=O((k3ICd7B2%z=n*2E~9xM5h!W&L8v2$MeQs6_h z>P|R4Ka_;?h9{4^JVPJwdd?~9rVcsdHCs?#nevKoHuA9!Yl zR50MyfMvy1+jc|M4r_2X=bs7~o>FJw;#Y!$XyiU0RZ9r_>YxzOp$qo;J1V;91&_hS zMMR5=TS-Y)GAM7Hq?d59n8}w2Y)U2iKw4H|-liY&P*?aNK_@as-B&of8|8^^E~%JDL0dE(8|x4-%N&Xg@$-g?@q&y_?7y z0X;A*`x6=wWu@Pp$V^WD8dUa8{)YR<-L=l4StLrdSEi8pcO=wA^yh#x6?Lpi)IvKFf{!IQZ)n>u1drra z<=p^nOQ`f;DuuB16baSnE43{V*`0yJ>D5Ty#cO0A?+;|NIpA5{N{=-LfF38EgDLq5 z!A*MnegN8L)9_4nD=GR9q!A5AzK(Zl=&cD4W*`+Ts==Mg1cSiLKy->QMKTv<5<`b* zJP7q-i@|j}G>wIqNuF#Z@uCgtZ={3iQ}r#kvR{B)O)C&+|2{k!VmiB;7Wt z7kLO2l!J8Jc?ESp3IxhSqMUELU2QjVY%m1%a2j4f9IOoqY%ci^1dp#{rH+W90L>zh z%J%0FqX@)oTlj4dvxXBfcZY)cbwlE21{Dc&IYZQsb?Mc{cN<(H%;f( zvr=`N;efxOs=UP}di!-ama|ep@Y~1lSgE?wm#CWi4ppTsHdXzGKx_xps858h3EE=> z;Mx_32&MXN1pP6U@>l*1=qpXorwGo%bWj5;@#drVM0j6wh3Z>y+50!(lF7GmLraM$ zH4-iHl5A?|CP^nzfxVIB88wNg1p9deLW0LMV#%dxxYO4tDE0vu?-3WUOPr>C@N0vv z4So2Pq+gZ#TPz!8xYAH3AT*j|{A$itRz@H|ykstO5V_XrYMgmvlaX3>G`e+{wO@|L zlDI-rxY}*5MxL6zO-)Y?jqbfM_@3>ISnQTu)V!16)6#jV70s0!3lP6XTp$Bg*`-2F zOe6S58CC*%1rTS~Kb4`36duJ#<506|Gi%Lb1mZ*2Nloc+yqVkLR~ZitxU>YKRQ#L6 z{4k~blJWQoE<^|nY@b}C_MZSaXEp!3IrFBHy@Lpj^hC-LM5De+piKla3AD*XfTCLx zNYmyf0*!4+(uzGl_!3-+YjVn>{ja6VqP2&ma!fRdE3BU8GiAhzx5pc;Nr0uOTh8Ss z8I+tlK*pqADIkvb(<6zEcF8?QvawG z8&}#oxL*xnuD`V+n${GWmda+59JYEq7{gLw%5Xp`$)U}wRB2vWWbfp{5y>KDDrplA ztVxw_CzEuMJU7(gxBVudYs^6Kct@Y znpB+w5L;uYwps8SRMj`;eK-g=QTvmIJN8Lf`L@P+vMb~L_z4F z_rqW#C^42JiHO^|-wLY@a<)(R> zE|+~|rAyA~&5|Ohn-xB8J`mmQc4#O)HR*$>GCH70jTLEcMMf0hH-mW+zTeR#=L8$N)_Ikb5xvkaNTjx6lDhhD|nHrre_<^1Ks~A%%pEsILTE)Vo!!aG%{?#B7Do| zQZsv!lt{q26c-d;Ovrj27$T2Fy?T*vi_`&?2C!u%ms6#y6v2yWD}`&n?BdH5+ZRK$ zAM8aWsp$z%`KsfpDxVOYX?mKu1cPw7nwNi~^&yXhlX`0t%1Z=gDNip^7TE9THasRt z*_cJYENT>@WIjo)h2LYgFzCI-r7RFH*+kr2v8CvYsiQtNaW44$1+b1eSZzJQ=?seN zUs@erTnt_XCWz^So=y0JS$Jsqt3J$`8k@<>(Dsc!tY{Rh0z0@Qs+1WD97!J!en^Fb zABy&~mm2npghlE3#VufY;Ex|#!pRVDt%*QVH9LeSi$2S>CPGzi)gsA`-VMql$?C1Z zNZm-w11)6-gj+L&^86huQS+P6SR^CXscehlc9Ff(h=i%*DZKj;3UPG>Rl~)xeu(_x z?52JDk-?~IJjAgMERxzJEL6-GXdtO-yh0CS zaxN~W)9z+7n67klaj7C`XQAY zerN)chE*o=oxs`k`%-&(QR@eE!zKx;xx0KJcJ}90X`vf11UEtePh~H~hVs>5tT|u* z1CGMPO{)0O5Q5PKJcdnq2AdF;0b&`4u#KU0T0Vaq9#tF43$7&1rOtRf@LTMeRtyEt zu#bY;uw>;9+GOB*JsV!Q;;v^XZ8DSGMRs|d;nfLh|zT|4|x z`U#n{B~lR>O+WAe;!j`;1P$T&im%){c=!`KV5_acNS6?Fh|Fz({|^Y;L-18o5lRsD zwPjTuB5pgxQTErQYxtQl!tTuNsLZfQIZWsKXup5aRETlI_Tu`NCkw zkV$-sGCv!5@c=mwcv>bw#IY$Sp8l-lpEqjoG)3zj?h4f*4(&iCGw75Rs&gkmpN)}Z zt=4wuMvy-;5izMt7%kNveFdZm0-{}yk=5UYAc2b;kR|cQv7`+s;~B5Y54$kmuyI&h zIuK+~_-@*)EVGA*ug8%DB2OI`+#>_-9>IVwNlCtOocogJ{=-fqCJl2}*#q!Hu}7S? zp75DkWObg1I&!sDsvL~!z6ZiZej87nn1ihQ3kF$f0_N(1t)-0KEcND204Hg374~0I z_sCi}X1pi5t@a2i*fBb?u;@RLXiM6KOG6 z>BD4F>!J)L3{bC~OgiAA%|Mgg&JI&BK1W#$my5*#~#0wN)Yq#0dtpbvmv4ohcae{K#<(o)oW z890LNHg92+05vPb_{O;+u}U41T&qnUm6v<|sN21CA?v<1!f?;=o}V z*t_uIOuT{!@9(}L6HL!0=?Ds6qrR(aF_&Ny1f0a5d`n!aX6PHo_7fA_@|ACCvhdu$?xFh-x!z{!-c(oJSmnXi)wt<20H>ng;0ad8A@A zd>O&-tpN$1oyVxgW*Db}AU`J157nXGz&V@HDv9%?TIl**mGG?;JgZ$lzYufK}1q+JN3rXUV17z~k zaB@3z=;VkI4+si9p>W&k4-EX>MJ%}VD(xZ|g1K1RsFf>!-td9@1c!i1HmOi|K;*td z%sp>)mp~TRK+@$HEY6U{Bp=KkPn<{Vd`<4=Vz;4G{}TmGmXKaCE5}X71o;%?dF8_8*(TT8b3t2wM|NR5k-C%;$j~6E)B{(tid`|H&6_~T;X@aroWkQ0)s`g70i+!xauJbu*>9v1r@RN;)0W^fTt5K0`B4kuj(r~G6n3zmHU2$ zhY0Zi9_?9Vm*L)8VTsyTjPl98NLZveN2Nw5h_cObgeA#Fr7kxWSiInb3H+AwpjC3< zYJA0KU>JV+alCeG6>}5bli;y=i?><#>^Gvbky55ZyzX3K-L?aC|iz-h; z6q$J;n|pt91H*D79FIh#GN-qLA)4`K&3esbTz&sdREKEx6kUFBn{sqx2p+#eut{^d zfOc&BMem)Ch`_kmib+w((+}yFl$cDv5w-GRpnUwCtNBmH4g^`2WSkR&0{S|Ni^KFH zNZ>{-54qsme{_IP!)l>1BHwK+!}5(rS+96yv~|2~1Y(PR@0Jm(Z6IWjQ7DvG3_)Gm zn+9Jg6}gBC_Y$QVOurlgkvYvk8hmNSiMe+yT960RX(3D!Hw4mlHVA$vR&D2hw6If{ zJP`%{$k5YF+36~JS+N<+0nMPWHsGES9we0pGI&wWxP(~BCx&Dst*vO|m-L1u;gy81 zu?utwmDU`zC5cCdz+uALFpM{mq7B1%mFW|8lu;kAQY!%BjvaBoD9!9dGTZ3|==VPv}_r|SoIMG_4hV6L@s`0MEJ4tjZcoRm@M%qI&4>=Cp@^K|H7>@;F2v^20ZWB z&az91=MeK^A~wHTLc#A+<6omPY$&|X<4!z?gPRxx>-{eb^1a8HAJLD0y!5KMkR;M; zTh%d-qui6cyeOtV!IW<8&`OP~y`pL@cUo!4hlA4D)*SZKXi-#J8?gzJaPTI!T|NZI z-$(t2??2kb(g}RXurUNZ`OV-@84Z{X;cr!x=Mr2B^2;(63@7I3|L#5#_`g` z6Pd5`PC5EM4w&7@eR>K4F7cL?r|9n=VNuCGW_|_nBA?y$z+Pg!N}2FkKKhU@{Q<RDYM`3uMw;9Ych-X(@vaJ+L&))fS>R{(^v&%G4a=F`4R9`aV~7{ z>;vpk)lzC%eo8P*w)fu$+!mnL)~8673FJIjlhee9X5AwjZ=IR|&SXq?pnc zVZ5>k6XSK{S$F|^OgNTA8)`_1>CSVAtXmO8`m@d{SmH!-_wH)|=A{RPj2OL>cX8x!@abRL1+to}$}PO{iSp;e!IUcRIAj zlh$XBvMC9p45hgG>w{VG`@dC=VSfy%it{iO6egE|L^G;3^tL0g7wIFFF_BxuZa0$~ zz-9Y9Bx?Gwh(e;&ah?E-IBtBouf326zZ)1zW|gOybexX7$(-ZTC%)*K2gYXAbNMZW z0MfwXd*bpen^hm4;6~|LS1Q<22%qr_$P=5wJ9tEuszyuDD#dz+6cMQ>=`$i-d{$YA zli0JHi}r6}dz2W`-yw|$RKRtgB50hq!C9xQ2n^xiGe(8Z{EqyW3F2uHduvhtiLD%{ z=;EHhNU~voZ{qa?inV}(K{Wy0k0H7Q=Dp!o{Dhr$4_ki17C;j2UCItckZYGkL z6-ZL;4_MP2Iz%fryh6Bi*QcK+XFA1T0qnzu7mvJrkR6GcF&MQe8y#fFQOkMBs&by< zRuFYXE_sCQ6%<|ng!e`_#TG}f-R9b8A-CcE?V%(%IB`2KxipDH!;rj7z9Zy~S(FY1 z5}ID5)h72QPj=Uj^gP63T$TUnqJevNCK>Dv1<4e@MAnH(0m#~p{b@(!Z=Q6C)|V3v z5;A5{I(L3m>d7TG!1V%q8YqAV%nLW5Veq+{%A$f@m$mUjWAR8z6w^ZOWeI6Ih`+Jj z?t1+^Q6^{~nh)NhSy$AVCC?(d0?t|dMq;B_;Ho;WAb1H*#2~px9UvlsgS#}wN)(0H zci0i&f6`THpsCeaTQNFDJOhmV)6`%|wu@AQn*QWbq^Ww5K}M?HrD4F9RK0)^jS8Re zyvsB={EcP$D;&he-j&Ai(a2EI>~A2>Rj@1qjrc{<&GoZ@+Bw^&ivHG&7-B)(B&66w(Z;RFQT}Qp?SsR$7+s`xOt?tFNYP$7Aod}a zyTU!|vz(rAvg96OdO!&&X2=_0HQ5INWu%8%6*5PqYvn;uaH3vqWEjFY_&j1mEmz0|S= z8}bF5i|xR>(GSU+4dtIUCxYC6!`3?@#mI-&?r)Yw_k42x@S&Q`hP?qyOTd?|FGh2H(d-97IUmW0wltqo)}7SQ8k-a{(7?qH(@@`7sR|1`NY1S4122 zpV0h3a|~Ko5mnbQNDWvNtppICKtw+^kX=(xgq>GBkqvS7>KNtON??r>PpLT^zH@U8 zWAW{do-mbgy2}YpM?+jcA`Wm)vl{%236VSh@UJ~% zR@5k%7LNv+KBslivwTIM%?#4B{3rn+b_$kxL82Kp7WZ-tDcQyN7j7+9O+?+tFQ`TR z`Cxg}?MmvhxdkajdX)W_S_t4r8Ww64r0hSGa%L=oO}G_IEW24RP4brdLdQ zh}I@*YT^Xk@fsb_aeD8G*tu+Uf{t0ukA00HoA9V)3HK8JzJ}VO7(i}fTr!$q%RKU- z-D`ShJ0%Z=ROZ6R$@YlpJMB^^Go(WbW?n8Ifxwsy+Mj|JrUB&o(8tVhCAz$0Pj{IW z=#~Aqo|R!9@b(}2*PYSCCFD^ztt9T@kILx5-Abxc1r6-YZ>LQgf)lygnktOjeec*Q z+{C{saM`thwFX%Aeq3aT*k8aNh~J#Pd>$qAeqF#`(koHLel@O!a9_S8*SMfPNaX8+ zhiirvv?D9GGJvA1+e?cx1?^JPaMwB2F~VA&067y<#o7QnCFy4m)CvM>UJ%`DpdO0_ zyO&*RPyYS{!H0QSt5#35hff0~-0`wQ3Ft|NxT3uhwf73y)J1T8du>eGrzTiyqc=_3 z1Brs=*FK*X{VD4GSMM2@>gE}DGQ-#pH;^uI1h(KwDT|MH-;kN;bY5@oG zn!N=vp)eFJ}i}hMH)_HUdE! zc!~P~cI=Wh*@@CkfSYE4E^LH}DNRr}-GS}du0S+v%7Yh8?A`_2Bqk;&ih=LhD_fX9 zMeiw)s$83^iPCHkmC`NdDi3dAI=Xb{`obA@U!0XCY6~MVMOhe$@=PyNe3AjK_X)8I zBXKzc4b`ZPW9R`P%u8ClHEM=}^C7e}TCr>-P`yyQGI@C*QO#Md+71~&vL~4rkP?$bhl#jQNoJim`7UHVva@=M=XQGu|0Efi?V=o! zH3(^xl?9j<5`;LMb2!kS=dhRXQVGMwyjCEZhYlX6jQ)0r{H?L#nPC_X(LbM)_9PI; zZX5_xLWJR`2@dni3om`!Wm-{!Lt@PT3Vykn;h-e5kg(Y zbX2)cWG))MZ;uJX`wHqQ7W`nF+~g&dm3(gmq#?GCDo$iW8}t{HfBVzwgGuDY!AWmNAv2b zuHxEZWqL(xrNq@{wnMek(V8M;&wL}0dw$gk8w<;%_)WdEtvGi(+a4dvO<$6{I4Dv( zSh$E=U)ceb+_@;EBL=}w&;1hv#ziVcjyfomn8cnB?zP$nc2@$5M3LSwG(|M;q?I<_ z*UO`{{YP5f#o~@feDFrcw?9C~xrJfn-F*whLV}2^w(5+kY^%2^sRR_mcL6>P2d}@B zWEG&$TJA&C=4bgTma@X96MRZ3pxcSt*WAEs0_~_CQXr=^`cu*T4$-X(fkzP!59`t*r+9?$E@x$p&fRE8RT071zZ?l!7^^(g!vu#f1@5nMJO&j_ zkV2`$5r*R>8kI+Vlf^it`0DZ&)+HB6_Fl+gM+KI4n#pUHg?9Y10@c(ZjRSh1QF!Q) zj-rB<$&Ue^a}EoXS&`V5(!25Cs(y_6J1bf`6N^8_(wDD9gl|^!>xpXBf5-PTE72Tu zDA7QIUn~qiQT|vW6CJdBwI|x>7E3xvqoGMJJK}nZM5?z}&cs@AlywQAbHnPQof>hL zVFxC;&aH6mf(Y4H1of~ZnI+SX>tFN=sN324z= zJ9}@y*%92d0KCgD+zLlfA^gBaMb|`olxxjyGkh90xQFA%^yflg6l5uk)w6aIP0plr>DIfx<7&eIBO5tQ<^W1H+-AC6)pao{AQ|g(HPD ziwrF$&2s++948$F!WTxQfDWKB2B^wxLS;r{jeBms{*}5)=cE=YnO^y;ZY3v zk^e+^>UiM0Qn@iTtf=;(aM=8cP9_e;Y~w4_NAQx<*f0jfs!(+z`dVmDP;hUtwK|Po zllT*}eu)~W@6-tG@CDjQ|24#0Oss+WPNk56GX$u|h$l550?bCD&ykC{&Buk^$)sae4^)7&ZbNHK-P-)v48a&7pvEOMlj)mNZ8#H{tKp2HZ7=nn5MR z+S-^Fnb%AoPEj)ibB!F23B=T)#`P+07>33+(l(U^#VQ19sR7qW-2X^`X{2 zA5!dkU?Cu|3g*<~0>uRbzNB`RV^H1d*^wzxn^IQ*=O@4q*Q0skjE%c(G{R0-kXw9a z9}FL9lFX*!E22NQ+exe<2*C%PahniVDn!Alt|0=#XIPnH#R#(M1|gh=MRtV-L_kWeh={M;M7E$p zbz2Iz>AwOV@MRI<(GY^bgg+oSpU!>k25&pkUPKf*jf`xQwgcO_4Y3HxT6!Q!v^`!*{XI$sCfN(~0+8pWsH9k6YEi_d8=>@JE z+8BgDx|CPs{yWg}S}r3XwlTG+MUD3;e7QXTC(ejS0S4#8}mHKpd^ujINY=d;=r*DSx=qnrk~-s1IlBcarzjH$EoWTD zHtAwDp#K3^MmP$O<@h*IR@0Vb<-(Ce!FC=9RcBXL^%n46|J;%oPZg09Dj1%2-dmM^ zmrAt2`EfiDG`ODwD;5n4Y|6WsFp^tvC+NQSbmUBW^e*W!rRRN}W}bFYb+WzGP-Q7W z1}g?rSxge0ax((n(^n)QjddM$HUK%SA@BC9&uiRRQHU``zZ22|-fdeAZiOm4=+rxWacVqCpYIv0-% z1(xMj%qgS7#H$H;wqn3)^q)4@^$0OzA|wm0-4zj0Z5*&5v1qi!6=h0!-ZMD0J?d2U zDBj4^VoYY#$Q03&AiZ)s;lz8^`|uu^LGS4A=pPWrZD{{%M#68J1p3L%k3Cq=HZY3K z%NA=BU{)P(Lz@?Rvy28p1EwtXP1}LJYPSXTq$=e@1X2{&6PLENVluPH>hR50AF0B!lt0>krdJVk`@$UMbVE{)Y9XTJH_OD@2eC9gfB&t{J_{6)tO zj2PWs{B(45fMI6kvC~oc&=N<0aCRh&n-kwfl_?NfEa*rW*XVNO;Dhu1f{}n=IC2a5 zbpi*Ph0St68+|*0|I8Iyo@4hJ+6Dxm$x>ff)vp4eNE5u?t*BQ4z>4zZ7(etSR;Rwi z>QwI-p-8u^a)bb)SxFt{LI$YZuK1w^fIbV=iRlw{VtV{g8uok+HcJaWAiP+pYiA-3 zE(>>tEHfwhsQ|M0bp4CYAUM4T0+H}pEHWKgc7LAVpmO~W<>p)~wis|Cvga2Nn?3}# z&7I;@svF*g>gpw3Ef^E1W`b|CyvZ`NK$LOWOoejsFPCt7Rz~o4g6ZvAGQ$o?-@-=uPfW zC!du{=2vzS(5RO|Jud_ZJ7BP!+IDj4BU-0EqIK#cTBkmub?PHpr*@z^wFA|u9jJfI zfHc9A7@lHOH{v1kWwPS&D;csx|p(V14ZG$774|h%17uc0TQbh1v{%5s&ZYY^^%;Z)4S?cKoS9cNZxAt7Bv@A!3=EO=YAYcTTCT4ml6Cz zA1kW{EkfIDhBWSLrJf-K&pL+Jmp1eT$~7B^zX?uH3ybJaE$kuE7sFN>^{E?WZdr`F z=_@e42cKHn_D$yO7Q7UPzvJkPWF6O6W2wEh%ku_1>J@PH-)9zcM?6`AR@v42Q9m;J z^cHk&R#22U)DMc!ble>H-tO~O8=U1R64oyRBxVJqtnGR`=MMa4nKT`^9 zX&Q-_OY@iu;@&r*jZ8~U>{|w$zG*Co#N`-f`~WK@%^}b%0-5CMxk4{tk%4YY*mDKy zBEOf*&Xf87v3j23;y_H?Y@_5#ROKanXOIQW0xtouJG1~cLe?dGMsP$5c?!oDvQH&R zIFd$8uTjIhBJ7uv*)*090f8Ya{N~>`IlNerD3>XY6+B9hA zuSTnD@<$gDR|aFJW4hc5t+CVns$^~YB}>!K6f21RLFP7!4Phf%8ga?$EV$a*ysNTy zExK_RC-!y!iI;M8ow+9B|@)D1#&A zhxPVy6!rjfEE`LJk44iuLD&Hxsd`N~JHOAyLYl6R<3C`i{=-2Brca{U27m@JNHMD~ zwrN^mt@*)j$Cf!+o0!QeX&WF?kGtrYEz4ENA)D}}Q?;6obWQJ(6MOz79dksxi>{ zpO3WL@IFSytMHgYc;SQIEKI^(0WrC57`>#Pn5?d&{=6AM0u86yi;DbT3Vs>dLB*_;wr`l~|Dt+g*6_bOL&fCXHV%(XEx8LW#Z3~f~ zvNdP@G(~Ua@zW@t<{vJbwgPI`4(ha0xT1xX)K< zjNL#Ye;E!ud7DPd`O#ojoMw|xHfnB&mk-^zzy+>~DI%_Em>i$9Z>-~E+!)9K0CX{pLCMk*vwn-~ibM@Rj<`m6pvA&C%_0!9{b5vp&t4=rY0 zaw?du z_^OKL?+*bI5^5j`NzOSbgkIBbazjUYC!o@M?_B}uO$4M$7U@O62M~xTDn$}digZxA zbOe_-%~30TH*=9KI` zby-koAskj&*FkjdYlO(2lG5<;nIj}skTol+X*k9SC$9oyBSLv)WZD(yII%Kxb3UAg zZQgJcTA$WId9ot{PvmbMBV{EJ$_B*zf$5(Ir$Y{xm!q z-?GNJeC`lmY(zZbupWFI!kksT^&nzTVUGP4;z*BO1V@L|7nC54>~PIy@eJWG_%O^U zFKM={CUEP-i|PfH0FZ!ESh{t#A-8stace7xTSt() z*~tY=%dJDH-6|_!qMJ3kHK>M(64)_n9tR%8`UM`$oDnPf zG&Yl?BHbz?dBSOjh<)`0F#pME91z|jcKb6#3|^{Iu6pncst#G^lr7`WVihkCi2N70 z*3z@6#W&%G%W)H7pDiwk-;ZE!JRqr@qZ!7U@6Z*v-;rK`L0_Mv?^jThPz^FDyU~=7SRIqC$KDS$JbOE3es~j!*+m4+g@f^DxxOL>Q zTSXp=k{6w>KyI0wIeIk>pC7QKQS^k$SIh*AO(fhu$?D>7FHogl(SOI!P|Kdt8UnEv z>*!}%r037`UqS(NSjf(>2KPadn;AX=a1OLuO<-HL&s>H4cIV-^>c7@`8*F$PgW%iX zu(kU3&dqGQjOMGI#&z@3T6L{tc;pqp*)~yc9c`MuoYStLrH$)o?9eT9-A4op`J6y{ z&)Z$4&kLa0DW9WRdzbbx{4*pQc)~VIP&?-uFgNeo zpfV!cb)cZU9lE9JQ*^$b6?ONlrMD@(l1)sx@n+P`Jct8t*M{&io-wq!iD?wu2#{V) zVzQ(pow1Sd5q=Xi-J&e~O4`?ghFisz$MGG zra%6M)!Ouh6GhA40w{_+a3eO+0&2`pBlyHkgt}_2({2O8nvzGGXi4=J%zGco)niRy z&1}2b*}|7pfA?l;L2sb(J7!*b3yq1~gLqS?{Elj#!0Y8(!V%_ZW5InYeYpi&ZWC4O zKLF~U?jS0$mq5spMHHgjE%zs`Gp(EB#@FmVa$r>d5;su2v?6mf?kkP20om6RoG#8h z7!DH7yA|D$4U<8BchGj!byOX*l`gTcNHRQnv{^*laDx0+4O7&q z`LmeEJD>A$xC^1$^1%xnsp|O(n=oOVrqBorWn z1heE23wJB*V)$u-SIdOi5E9P^zOan3;~Me!i6u01++G*ZwTW z@D}^LWEYeaWu+FEUxlZLD#0NI#e=q3pUOXK)hqW}`!$;4b9L>H>RgpWEgo$N|9$8} zlS@%g8od;4%1+Vx%oL^1M1o+fD4(!fzLg}YR`lY(=;*(+vY-wQmj8=X7Hlz)_~Shz zn8-!SJv6ul{~*%s!5IorI)Ih3$)Za(_)?`GAk5b^bvPTE2a$L_7A_xvCQFbS+j1Wx z7gXo!sSHqsw!Wum>wAh4gT(e62I6|svSUpBW(O4zogQOaL$jkvB9%gkDN=3ek&)%= z6}B~q7q@N>4Ad*H0TCQ)GcREDbe2#($CF6kpl0c~8Z!Lv% zAm6Jv>1?8B9-vt4Eh~rUa0+k=QKzQMv9gfQhZL=5Nzo?g6fFj&=y2RW^BJDUgRsMp zqM*ch9+XE!{Y+d%5pTFhluF4WD2W<}v{`rA&yt?hc{Va1X2eF_j`b}#E$VYFdK8p? z{eGc^)8`!AK{;C5S6ukTL6eqPmmlNFs0wRpZQOtK`Gqj`Z><=y<+Q#(VCI(ipa2fs zk8gzL65(ecXs9#T5;q7AUvFPA@eJBf$50BTF2%E043Y=}q@;FI&k}vg6C5JkKL{7u zewOiochB>ZD|~8|wkbuMms7NB-t&S+T~A0)iklNcAu?RwnF$F;9>b#7!}`dac+mfFF}ZS? zf-q^sTskxiUsS%LM$DiKVOX}c1hNMkNDo8gzbe~RU-k}1wd3iKP$yg^jG{A^zdsd@ zCRzIZ68qrJ zwpr+mAHE8|Nivw;w5SNc-@l0|5RFsSfLK;y@d+JO#Gp9oKO(^5Sb7cmO_Mga+Ab1b z^O-yj1x(ru-$(FkzoAtk?QD(EN~}ym%=u88-=g`d5`+PvG9Sd>-O@zQt>lPC0UyLM zw=owIS{dFy+93DXT15;`K$i7>UHOBs6}CnmS=*vU-u!xpl%hv; zFKVQSojr}R;zd#V0;g{-L}f`qwM{Vx*>f95i=mQD_HhkOL%53r1hRKHU~tt{fG^k` z?JIiSrLpQg%~Jx^58tId1=VxS;RIs;i;DNO{{%F0*fyATyLVL1I1qP4j!Oty~c$6EmN>L9tgL8{B_uZSM{<6jHL^MgY779>CC|WcPopJCjLb$s|o%n z>YHt0Q{d4eCT-KIK90~lKlVq4#p(4(v@ z2gGBE4W-@|PAqMWmlixE^~S$f9(8SLjZx=Hc>~#X4yl_7PohBunt2^K;U@o$CE={d zT<{eYa2(`HDqtr_F0f*m;BLnmE?~pBSa5^JPlG$+@15R0C-Y(&iH_fNfctW6x+ z_K(+&O^Qb!)lZ|K>odoWVe_-4 z7qS9f%C(16r@}S|yI!{lW!&a5)=9unwzz;*Zd|6=6N2FQo}Wlv^c>roqPI1i1fU!* zNa&*!GM>124$9Vx>)2 zpTXEs#3L&%*6JlOYE3JjxG?)|FNpyutQW6cG@%Iy$d7rY12K7^y^>JCPxyRH1@>qI zV%ZqWq`g1Ih_Tb~At)5)jg>(z@mVtPWljyFR6+H0gMB~1*vL$4-w(K_5pMM4&8)7u z;l`HnmLWsuxmKeT)T&w=jOyQiy)bV4KS2=-x*FtUs2DJYNGrrce3c^C$nB+I!8kY_ zN=PI0R5>nI<4)Hq=(2kb z4B108N2*BHp_Ew&$kiM|DYL|m>P&IvtLpPNIVVkoJjyTxQ#?8bNod87Ac>VZ4VxdD zB6l_HL4YqnimVJVtQw>?W`sk1WgEwCjMhminLKy{`5t^c2b;HUpi7GLLTndQW zrv4S-Vfv;>KNM9&Z1F=sx3?o=Q3wssv7(?mh>NWD#SclMBBr+CvITV)yrFXIzj=y*ws)I~wr ze2h;C3O1uIc6f0Fv@@x=^z#zpP-CO6Lqd)oiV?8`?&v}WVo;*XAieIwd5SqIF}NHV{xnxrjjO@?>zo;8wAO*8s`c+FTT89)!SDPZxh0W8gR>-3t z66uAlAGSi>4UOuyN*s?G zAjyswae%2mya~m>Qz|xPgn-09<$HvFl}wK`aq6^?esrFZh`2>)zFBj~U|Wj%^ux>UyM+d`NkO9xhsl^EWk&j-kbN>#I51L(px!_ST#ukl_6Y^m5S{BEC z+H23=av8-z#5QPVM|8(2A!18-QSnVGI64$k_NOHXPi!h~+6e{xqEWVzMBes}e@6v9 zOA>n8*b>tjFg}`o;mUR^A9u#EtCTWS#&JR!f0kmH7ZmSkAWMKN&aLh_`rQe{nmDiS zaiYd@c;gl=O{WA@ql|bzbwQUOm&PP*P-0hrSb_Jdv=bMXc9l4%q$XFKG6CWT->aab z?MmDz78mIGWr(PCCq5;if-=7xY0{U_vr3WzmDd!t3_HsNXH8>N99d57204IZT(DU{H8Z)Z+A+vE}Jx z#7G!kW4sxeb^~a!h`{`W7d6_v3rZ7URmd`(og%hpUok=$9gCk(>21atEmg zBakshF@t!hgqHL(s)$R8L?iqf71b`*ADdd=MU0msRS7h^KU%K#91*PFx%kY`1<$C! zOj5|rb-NA#=*m6#56nz*?(|`T^Ih(7lH4G*(@6tSFo<4p?}0m;Bw%i71r;1?htuL< zGFl?hgyH^!03UD=@C3I91x(?y+OpEtLQ%ZL?X}UT24O<6k;o10o8sAMyf|0~GQofp zt}7>Gfu#-^WVD3J5)4MNO8D@qAJWgs=9zdCVh)fOCQG0{#S{+4utpETa(xF7%|pV9 z(t0!6;H=e6NqW`-0i}%i&~S@BLorf`5;B-o931M664-`e=)vn85D$H=$TV%n;w7rl z4Sa}=j}cY$AnAHu$@UV(!O`!{a4n#vrhAe zs-8uKd-{72ipy1_HYiY?u&37hXk%VAEE7>HgEqYnMpJ53P%vQ?URbHleX9Na`+bbD zdvzcc;%H?3P9uz5<=Y~)hSEc*2P&{l${dOxdYe>aulVMDz9GfSxLj0~F}3YQ<_K*{ zWYIK!B!)+#X+f8I&cJi)5Y29dIO57^Hol`UI`8!#I0`MifgsOQ)r@j5_LQzkG8-)9 zJo}m-06wQCBMC+AQ?p+X3{M0>HJS+#(6<&v2I~(Bk47PL$=jq`LCHS&KXV<{Uy_aT(E4?};c%Pao|{jgN;o;I+EDC!=x1B_iQeBeX%XDR)|O3gGN<7}OZ@gAJcY z@J<6ElVagOvJ1_ zv=A>Ss?}DT@km;Kh#tL(A^k&0Qb=PA9oZe2Qpo=kE9;xENG+^h)Ux&d_x(a=aD-_2x#(zZ8=18!u^HoezC_&4}y)_>J zah5gmHLE&%dzgxC;h4rvRZSh!NW;i1O^zbXu`im41fFqVQ3H|d)l7L?;r-e%UGLW) zfTL3_YIGij#2IGQkSV0U$8}5@WX2b>cmi) zP*9{qc=hB1RhDW+v1^7=Oy0Kft^;2uN{Q|>jaZNW5Cl>~T$u^Y=!2NTu#}K*0NG_4 zeEc6m;Hp~*&e*-{U44vjfiVjOQ7ysJX|)IxkiZHkqFga#wwEa{`Z?6i{M_9yEfvej zHVaE$WGYw@&K6%$qm^u(MP@@}^T+*-xypuCimPz1FJ_}xaFx8mXl=j@tIRCOd_sl@ zW*Q0Fu9%?giY^?(atRR)L_h5FJ3-1~CFTN!B>Pv-A9zqcZ9*tQF|}3Vz+80ijqLIB z0P^M_JkrGqo>^~;%e+ry#m{UBg8jR&&{-{qa}NR2YjmcoKB@kBs&l7-44Knx z>5Qq`*0|(P>D?{1{^7+%inJn56NS{oRgLf*{P;Y7PtP@whSyI_>4KTt%qC!wW;S=b zFrU^Yjp2*1RLpGN?dt4s0^V87MGhHqVr9$@^Fk`jo- z5D`mIl?AX@s4AHa)y0}{+$xJ;J-ee@jZ4W1w%yaEU$DRrO$EwZ-=$u#2*3|@yv|($ zQ2~ETSFHA;(NbIxSsEDF1JZ!HB^u)Ur5MtY9wfflYhH30&FCg_BUb5&8BvY|8f67! z>jj!f($tp41Z`PNkd{RcMZ({xwUI2kEk|RDB&E>iK^YMjiYOQTm^-!cjSJ+zg$mX6cvOpXCCs6_4x6A>w2#T|dy97s`ROJLgSlMzNNgx#CeSd%xD@DdS zU@+S@TMu;Lq$vHl5m7)IVNxg}7mdTPIsSIA)3EsoD#;6MnL$K&(iCHe*Pr9`ul_%y z8y=<&g;Qk{ypiztAnI3J+i0qdaLTkD4BDZT9z4@h>(O3;zi`VtFqoDgUN<5 z4338Y&Xr#gY~c{*BvNN(h@Kmq+b>RRKoyp1D-AU)ybZxuL=m?U8^(DnXAA{W*}JxS zBi7>4P>e{QR3h&eXrb*ek}}k)7lM>#Q;1U7iK3g065{R6MwCZ#N3hW}IBxNcrQs&D zB9-at(FO7OCdWOI=7SZP@Q*Vnfe-qXoAKrD$w&^k;60Ej31>X{fGvRYD`2k~uC2$z z2;TX9j900YkmquX;hzltuLKzU&=@Jrn_wX7-75UhOh+07+ly-HgsP#)cpN?g{oAZL zJ>AfmEs)^Q76NPR4U$4257PJ&^3A;wPL@3BOUaVyx~;kK-7j&J_MTG+1V*{9Ge$Z) zs=F0C+W2p?kSOpQl$WJOdGTdD=m1UvD^2bMH^qQMnU3(*!MK`vsNozQeJBu*u-7O& z215Vh1=~2$^dfR_;8u$D+yT+1)>mkV6y14vHb}IIcy;*T-^LR(xN(sqk@$k@5Dn$V zi&2;|oNvk}rM(WdvXel`&4hjpG9wP3J3fgHtT@EIyG6!z199xk?y0XXMtZ2(zv0=6+X#zJ7PCu6q9@vD)beLDA`5TER@QYU zs6>0N1f6Ja@i#_QhxsXW4IVu#@eS5ra_U5BfOK%`sHu*pHF-YSYW)WzlfK0&WZ~31 zFyfeXp-^*>KJU;tW?#4}q76&D_!j@fj|WvTN)o91cbMnm@r0$gMslrV-vRDB0kv4Q zOtn(B)Y538l19b$orWh9i3^#;AkT>h^(;<-z+*ARo=3QVuql3jU^oiBrKA z@wUA}!A`r4ToCsXRc<%@P|||A*C>m_Cv!LCyo=Fz|0+Jig9}+=C6T7HIpjP$j)7<4 zmx&>JU&!Om!O7`A$N;5MCJunni*dH%&6XHZa}T~u{Rn5KdPPF4*n=at(o$U^dLCYq zy#J9=%D{^~-iL1@D~uS^+wL_=gsIyU9`K=hwkU$V#EYkfI9?CNcXS#m)=xJIh{PYz z^V#V}>4J$;-{e7e@QKeYFz6XZWs&PgBO+}IaCg=Wqj(|pz=WeJLPL@5U)H^Vx}wu= zNVe71;;q zw9i+GGarK!YB+qmS7splXQf$e^UxfpU_a|yAXkr#CXd=vBtZ=|cT1VE&o#CU;5YoO3Dn4{VoqHcQl&R3r)GofN;HF!0!x z3r|civ5N60!F=uxjw&M_o>a`I5K6O>JQ+8mMYGO@!O!WINh8~T3X||gsR}>ClUA$I zxzeJaQEC1n%+v+Xs;j|;!_$62Kd%U)P6qfc^#tecwU`7)7DuV|YyX34<7!~ z9He^#!G9z;Q$@QKbk4AE3l&s2kAmGRFc=%}KP6D9l>n)e7$?^N5dHj>SXX$!sMF}g zJbLqXDR4X6Dl&0l5k-xshFOqf;Uz*TF;wKfV6=uwE>XUEN$J4=6)~!YJM1=f7fh*{hPk@0JqmZ9-9du`e1zb3a3fcc*)H-}bSitbW z`|w7&ypG1C*C+fcsv^h)L13TLKIl*E0}+HGZ6919uI`7#b$+WqSHpBDCkxfti6dQ zGB=`$B$&FmZh_wni-X`Re8Cq^9IFgxm;MD`P;Ve722G3tN9VIW=O%r&b3v|K5OyM_ zBAqIu+<;9WLL24Wx6mh04)4?uInf9H9Cpa3OwXH!t3K9HC2PPBCEmyvK4^JWwq5*C z_D%gN1(v~EKZ+O(vTyPr?(9|pPdvhsw=oDpV^MyK6OZS8k3^aCw>a=vyts|!XDt4A zix(F6_#Fj|#eLJgu=x1zXdGsFDS>c*?mqy6z)C^eN&;c{DuT0}=JPME|2KhgLbTAw6|V*a*-Chp%in!!a6)a6B7z+@?cAv~K!FsvC>5Fb3ux)2W@ zqHphoX#MDo3xSo*7#vwDtVOeW9UIkX+_+hbj>Cs`AJTJp?{3}859-#V6y8yUSWB1l zfFw!+g_LYa1#_Y)C%nQKrB-DIRbpB5#@48YoezPNOTgY9t)mJ+}mJsB3C9`yxI8#eZc_d7l33_ zaE^4jan;{~3$jO}R_7b?|SG?831PbS;u zPjJjnd}0{#@eai z`sY8J7yU7$7H|2Ps`}vduFS!aB}4zO-4ipO!L<6O%@Y@%8Av2Yu@hc9W{Nh?G2UkF zp>=g`nTbS758eq1DUfB)aP(0?rT3;uRh!o|Da7)>n`VkLFEH8v-=@LX_pMb#rTP2s zhCvW`2@YJfFkTF75*G>~O7RtcHs0}$Rm8qP5OryV-O3k6gmyr1xs^H3;G)v#n+&|3E#1ZsZIh>=U-IAgFSxY z(RW(nVg%U21(jfYZM)sUv5~9_g4lKkuU#-15H=yl?jT1pCPUuDQiH;~ zNtD43GyFQi2V8@UJ83u8$&RLLoD*>7?RR%;-p(IvqXOneEi>=|%f8UQ3d`5@7h!Kj zhlm0{gCO=~fM44Tex5Hr0_ysT(wX|~jiT1N`vI<%H~Bq7@f(X6YpD4 za{==40Vd$B`OMZ1WoC_yNcuJGfTJViu4AE%jY8KCI0srHzX=_(3$8MC58?}L>k{ch zaKYyK+YX|>9me=wehel2CsegTF$DmcOdxw=9~Ur5ub!k{p~nx_NMU!hq^93Rz>_|T z!>D%=+Kc-IOgsSm7rbLDA41o*vK}v6U=?#P@(8DD5 zs*oH*EH8*fy(H^t3z2^z)ME=#<0I(C#`YluPd|cgG>%h_!CmmEU>i}?Q74w8XyqK# zXDiY4qiDy*^KXIxXHomfQ4(ZG`N|t-TQr4VkXaS#r6lF$g&&H^s`ndg-kOvsvG*}O zgrTrkS|B~Ah*)_qEB5XW!L+kzCFzleH!zXKg;DjB6Lc}hO^)n{kY{LT7{mTFOwap$ zIJxJ}kBCg$1CI07NvwvBL@~sggI7vKPIm;WOW*Bw*6#B=YQ&MzRyS0%D z9&CYaWBe&zSiL>L;V57P{QZ=3d&UvGSq78>sXr@T%;fbu!I!@S4zcTJCx2>TQ2mM! zOpE=3LqPAT*k!;;GsZNLGGen8k~RYZ`JcadVnPhD-lPGLgT_0j$w7luPuRcW@~Ht@ z7MFg906)BCQRK%ZSyY_1u&R>PtA`0hazs{Ezaau0dGnayNPyn3OXDKJiQ7yp94ywH z1%jri#R3*WAqGVUJwF+A4$GxWM8znyG~yg#GhBb~-wO^GtD`WeYXnLG=tLsITJlAs zR-^My(E9}1b{+^pwE~9~3eW9Ivh!Dn&yY8RxUJS^-7V>jA)N7x51F|aB*CZ+|EdVu z$Q5~kGF(D3vT=`;Xj_+j|Pk^SQE&&&G0|D~U0Vai*QaENj zgz2zk_AQPU)MiW9C~>fO*3GU`g1Yg#gRLVFHXF`lS1@zij)}(#D58E$Dbtg78*j4G zQw7OaX{(^iSh6-G%m)O?zWOV#(rp#Cr4v_SGsW{eHz8HBA47p_SPqh)*>GC4G&&qO z5kW8`0Vme!5`EL~?)Jx}u}*vk9dsItc>5apZ7S~v@eh49?hJ<65V{H*j($4NK|csq zB2$Y_t+22R&J}BCp+Fg}WZhsDf{yh(Q3h=xTFFmLzrnXcP4%VAVg&bYU>-zo>2*xg z@My!5bSS2JRUtt1D`Uo#0~Tug9v-}+D<46WMj%Nk%4`)(>TDcrdv9X>XlB%d=v@xt zUAf;Jpcr<2XBtPyfNU~ZKFVcpy=dka5-E26=2&wqJ}#l}1O5xyewchn~#gyBO7KIwN%m6T%)x=0{aLq4Lawu-b? zJmj3?;HPc>0Fp3|=lYxDQ6D@WyG`t!VPOe?aX?qOKNVAE_@o4^K!J16;(hujp9gS8 z;DS5!0b`oa9iS#@4;lV$BH-QcP~)T$V%Tni9lL`u(;3a6QZ9g^ZX#f<%3UCqr|x_z zV0Wqi-Nj_cCeI(daG4PW*jox?*4|Pg`g6qrxK8&Ze9NlEG53gE&_DZS9!UaDUb)8t z1(Xb2HzgT$dC{8Qr@E>if0lEYPn=9KSHh&2%?)9O73F;%=!1`280tm~#~*O3z#4{K zBpB?yro z5lvme7oOHDR|2U1Uxfa88`ctND}gj0rhMQvV4IJAOgN&oJ0mM&e>3vKI5_RGX3jj5 z8HEObi)Sj^?wr{5c}bR$5c?@DODyZnqeKP0XB+Z6j#Nt{RHDAGJif* zLK?&Q+55)-IB{-qbyWT4A7}rL2+PQ~OixN7S2B#mI$RVh*ZE;&oq_4~$eFJ^?Nwbc4le*FyjC(6*G#U9nsZ)z z1_MY$TRaqA zOQWvh*#4~TVa~R*nc2l70l_1FT}TnptTc@NJAF-=?2x-X-4v~a`I+h>#<1$m0IL?v zFinHfwTr^ZHw7ytDA%oV47Q<;O<)^pmy3pN9|%)Y(MU!v&)&j|dpjUY&J8xM{qU=*2s;W zA*~vZxz*c%moEuz$okx4(P5w7jCD@12_2E)DRg5jmxWTguRe*&z%XWWuoP1Y_aACKHA?>OkY6kaiE5a6xoC ztg1~W3}R=i(*Dlw*&=9@3D-K)5iMpR6WJnVuICIC{R4Ec2p4SVggLOa)+Q5%2X{tG z%xgJQwFv(yhRtZ14{4}DdCLvYV&pxd}%nL zJ)||RTD&Vjeg;#5B91u(x>5zHbl*4dHA#_F)t|!>nWg3LXj0-Iogp4SluYt|53`FW zArI2Mb3z`RjGP00P*1b8uXM^1Wx6|fKaXU2cXaDK%MFpU2iEBgh(4ePgt>Dw@N7+| z2qIV<0Ng}aPsnopKM8^Pv^OSy47vkPVe_77EHTni-=B3tJfk~3%or%7-CCpMRyj!l zk!pL9rx$J%B;P-d)TagaIj$Ft(JY)>bc-_a;vJn9T=07@nhz1g-3p*a5*8WWqBr22 zwPE=z=y5v6nj~=I+~Cq(RLYl7PG)={Rvi&sSfURK*$tyioM!P{z*fN7ao9z@TjB-P zjT~k9rNx6q^J&0UyY&T}Jpg-q7aXO60ktut4KWg1)sT|=p&)-zeF$+YMQTC82fraH zFEGfzKNbS#kFO|@=+z_VLuE=Fk?6oD5ikJlUQEQG)!HEG%>Z!X$l^2)xu=%6L?8$_ zq|B9U-4gW%0v4Jik4naEOPm}M0jZ2UAf_du7dm<{EK3-~-1(YSW?>$__y{5XSsO{nB*&>Emg^5Dai*X>@O&Os@$9l+Pi;%McIO#K*ZIcn~Ltn=u}{ zAe>%Vb><$1ry7~Sq+LpUIxH)Jd%V}xf9Ows*4Z0-0! zkkr$17{5(#NOcOA_VNyrs^=!rj>hS7>&z1>9X-}fMIYja5**zs*C-&$Wza1xXzj&E z?<;yUDlon21L!4XnCC0}qzYaKP>&Hbz5mkNaf1J!^j2{sO8+l<`-}?TL~r>Ot;q){coV&SLj_srEn8qvR(hL08r5)+;D%W ztEy4@E-`31r1T+B1$gu@U8dr~l_fq_eG(l3TQRF+>wlZH@D+JUkw*CMR6`!t{o+c`afvi!l(Y3PIPoNrfGe463zj{s-< z_`W)}*;Z1oA~>rYO4d*^4%g2!9dJgAIW=fN3S9zHJUXQ(Q&>z%(K*9Xbk49`v(45X z7MgI*6o3+AI|@9p}RKyTQt-k(ra@-&+r z3+>UBhLFoxRm4kr>Jv~?)kef^^sK5Zzz1*I$8}WjhJ6f7qYwVOkE03BHXE~!L5w7B&$8v6*yt6Rf{YCf^De)mzb4*;^RB5LK~NzG6;OC;rVK_+L%wfR`!p4DlC% z^0&aob!~x`y5LE=lgz?0ZU4)7Qi0clG2|FV<&;DuW131$d0i)L-5>hV;-PzNhvj!0>lTv z$hT3|-l`1*=dHT=win3-FGB%4sW*GaNpj-|-mkxvOYC?D%WRX}AIm^;Y}hXHuGdyI zUyctrAa~}wPWsxhoUKyttu%+>K5MOz_t`vRQcEX+%wB=7ue8KelE`J8F!vdOSS#41 z73tsT1#>D0NMVm6BARa=uQan|^B{Yn)h0sLasObm)tJ?0F>!pH%EQ2I-dc?|)7zjM zvThOx#|#TDbJAcFiEK*(m3FN_5vz%!uEQ)cqb(+tsD^+N7|`Gl{u|OAY@A|wGRYYt zcn!K>-0#%RYe5OlxPP!6noXR+38x+K z6D};W9`m?A1c5-SI%A25w;=@N-(I?27s;*i0uuzt#EN* zgIQG6@2c08t0ip25cvGv+7)$a6&b#CBR;pfsikJn+_TUq-c7<5OzWn2J;T5J5YHh# zpsMy5H++Fs*-NQScW2ccn*e8bf<4{MVxGAUAb3m<6S4oe3{k5Fdv+6AC&jAQ?eIhG zQT{JX`18XeE1l`^Ln#~@Z(%Kc%4XpDgX`Fg37fHqbGDgf#KFyG1&=Qz4}8z=$gDfn z`6A}{hMoF*3k`fBlpv8KXq6#ea1))<0mlx?8!Cf-BG7p+P{Nl=h1Q@C7N1qiTy-hn zl)BPaEKftLbnj)j-&Vlkj(~@^`qJH*)B#*D2nA_@sQ+PKXZ`bA@!r$}FHp^|&;;LA z+VrD7N&U-Bd_e`ctN4n|3$ZmezND{!Z2}h-Us1NdzCX|hMLDax+z6R_0t?S^jm_zY z+L0f>HhV~yRjuGmiWQw>=mwGCR>K}c#chC9ZHzRQEE2*s!B;F90Cfrb9Pu!R zZo@E-2f$I~^#I~`WOL$z!&Jc6ncf3wCp5k%eM28m`qb|iJ0@%ipIsrar%*D>DuWaY zLPM6w{VnhVuIp0Yz@WeO10k9fMjJ1eP*u6hPz_U6c3mGam4-$sq=PKp)#wc3_X9vh!Z`AGJb$QD$EG4uMP> zj3%i>&mr|sG**2fGBv*3rdav|Ce8FV0dNO#tcnSRLFgrJ zh7ZShQBCtzP$@9Myge3QcxYw8k7$Z%W#?EgTKSg>IGnHKIA`Cz_t6JLD{}#N^nH>F z_=6W-A5_{;a0>J2Hr}~}YX}a7fuA@w-a{~^$aes6CYYoN4uZi8nN(1109Iqw1UUyq z)|>#8sV2`v^kAPu4G&UF6P2LN=<+pz&P{aULF7*W)tm$nIc9LJX$1O$K;+WPphpBM zJefe6YqUEA(1giQ9dh1MuC|Y0c=k1ixIdW)MWb)*VYa~g{$R!w15K!RhVVo3K>X0h zk@f{&eb`)RUo4X-2_SO3`hYXWEwJkP#mdx9V)PM*sLUgnw}BoQ4l4|L*2Go+DA4E) z2h&$aF<5;t`HG^`$m$C@p4*9_Tu`}BY zjh$TZm9y|!3^q_P7H?aCm7eQKGRwE(N%D4M$G@sREWv-7o9?V z*kyc0p^pKl6=8VxpQ)Xba3T8OV~vC;qa{yOX}iR+pbilh1onoP0N$ekkmT zlfq1UvHcel)-FnM8ylm^B2i(t$`IK$5jXW{%6{aJA*m{mx_Pwp|mai75u2N8jEE z&sA5|hq6i|yp+Tk-tz+OtQNZ%6!-_cI&DdeL0_hXN@J!gjTj%Rv}fe9(BrGcMS2oe2HkLcv*NG%jpD09GTmxUOCXIwygQ;i z@wgS1A=>`VdXJDl9DdH=JehfHm?Wi5 zj&}QC_MB*4@oAtWpJ$*vR|jKnx>gRktG=x$}bAq8!+n z`UFE+^cVuX4l<%jP*DwDj1(tzqeCKi3Pj&GsX|el&B+d_z4`0pKiv~Nbc&; zvXD_P&W=(8WoovnbVY#ZGh3bVfXFaw{E(4r%5xea26K^~uwzZAGdFLcb%yechtDr7 zbEsr^x|W+VO{97E_#9O^^-g{=N`!~Hc+|OHVMUxg z4$lj{!eV$!AYAoVf>(bI%VfE4`3^(*s4z|7D~7^SU%XaG`TJO&JjEE)2@~QoG|$Sb zkJ~f;Mc2nDxq0>PoEtrv;GEoiJ;CjbzDMv*Es$&~aJ!aasi6g};7Z2H&BtsmO}ve}STgEOBu*&zjUIS-LW1#G<8z6037DeKUFnh*5f&xSxmj@U^j z9vMDpcR%!@lsx3HI%B7^9e^7v()-4EF@4`Pc2 zq4n`*0Gw#u!2r1bPjgUxoz9t55y*@`_Y35P)GUCj6-1&wQEoT!eWYiMu8r=#$_WqR zuE_GSY&RVmxae`sNMB5d6MW^&P!~XkPxD1b{W6F;^xPj&)n78usQq<2KY;KWwga@! z4!Eo$Qf^7asn00dxeXU2>-yiwyyFxkE zd@l^!8eER;UlIYeH^HkQ-N zGOugqLI@4)k}-21SRgB6xWK163i!p5zfs`%pjKWq1S;|q9rt_j%;<6;FV-r@4?FfshLg$t*WzEi@??i%P$PnR#|99E2-6E#bTvg{K}HpEHrVpSOd(ux zAkzD_Co#icwI^cVQk*qH15TJY#?0qC93k$);NY0WSbHpQTJf9 zfQvv5@xNnWDxMuX77Q-*>1{as6*!JXBgvE7i8~A~x1t!h;+W$=F5Qqn3m(jb@`YF~ ziu_e>NBF^}Oq&Ub!9!uiawOiPanvtNS&1oOfhX}E!M7I1`1lkqeA3CBtxybaR7@0J zJ))@Y@h83Tr9~*dVr$DE^p(w`cM;s9T5NL)hpb&#BFrix@?V1}x|iU3W@7F)z?|rx zNxKtI36C)>fA&7+*+LzIyab3CmfJ3Ho$xw|3T#Bie4I%9@E{$Ne(};{S(G&_M>xHS zk(~^Ixa7rQg}+J6$~);ARfSWTDZV;Q)B~%G7*{wlT;OINAb#&wI7CFAVOES)w5XqO53vFuO((*b#m!V$xZx zA;B|00(@Hp^y{3;^X^%>=xp&YMCY7%8Hs&WTAsrPL_pAl8RFpwkR^AV^U!`cB}C_k zI(h<|aw*p{DV+lNv? z`K!+D{gpuCs%Gsp2<&X;Z_xetTmv&9k|SWD1pA3W?3cQ*q?WMy!swVFvtHU<1K(3t zC=MPT(8KccNd|iT5~7}zz&ufJNp_CS#?Ci&;&zTE&I9Pt=4AXWU$*3;VnYDpS7)PP_m`u~fynhQSY<9QT0B$}7HDZ3N1b z^8yvxND`d~WXOkRt%tHbHMurP7&af8n;zl=8%cg3IJ?qTk4KE1^$4a9yRdvR71E_- z+#`}7=m{ns^+GD(tM8wW7;6>N@o@v*pZ z2vON`DAy3^5Ld-=i!ODLON0?d=C2gXQnDgU!HP6a9nsEq)X@Zb1A+cV@W)Sxdr?#- z&!%Z5z&iZxk58)0l`T&K=OmF{AGh);PvKM_hldcj zW#WtQ1(z>JJ$|aCZ0@vI6?DMb-gf^uw>Ps2a5(cH!eMC^HAI=Js9O3NVY)tc7Z8Zw z09p79!_)hZ4pS?lLw?{O`*SA-n4ZMwNeNndLl=yqVnPj^x*lqkDFyfeELQ*-2WTGZty_1j7+cdSBbxPx`SJBDS|1>8 zlWGvE{;r8uy1ypA3J{VMgo}2yAXt^U0Kw{*hX4B-9j>W`s&wKm7>}UQ+W*3>$VTeC zwZRv|c0&JMeiS^p*8NK~D9z@EC|MgHLKTsBL8v7iHhHvjSA|9_7;ee1h#K87n3uI7 z>#cYamSe$nixQYZ{$zNMI)K;DMpdC+!Tjw|Ix(o0RhBr9)|=^M zMJ8;RmKN6q1B$wi6ttiFP?re_vMrIX9@^is4Cr1ky9Iwh-EaII7_{)9ov#?1 z-6C6$>RgU*L7%SHYXpRpq56yC*4dTiSUrX?9Ih*N% zNjAr|zDNU(3$Yr{gh7!YZ9h&84picLt2miCy|FyTj~50{MR38Vjj)+FWMvJ@-WaeZ zxwrv%)NsB2jWMd@C2@}L%4NxOoZ)8(9_3Gy2RSpSMiYEK!`~`vlWnrh0?sFCqPArw zYFlQa(t{y2k6te2eJyUhZBe{>?xqladj(hyX<Umgdbc zyw$leJmPQ++Cd=pUJl9w^MGf|i>0EVTAv_aF**;@SK2r-E7hW)`j~fkEca8bV9{@O zPywljLZb4Bw0EttIa!1knav%{gS$&=fl=AlqSVHqi{&lQ5m<-At)HvL0v()+4 zPAE!@WmOMo^ZE6`5d_z#gLp>DP4=|CS_staL4$6s(J4Pp)G!Di*tl?%;MH4$iGNLS zdftEs>82d!&EAd5BZ>us$JubsZ9Xv=JCO*ZFjvjfma(I4E56nNEDxOJ9i3-ADs$pY zEDR^kOwzf_tF*Hm56^LfUwS1kXM{1^V>tgs7>BLzR!1*w4Cg1uyBV-i==E*g!P1c- zh`pp|9r)d})WT8fNfqvV4{AwqsX-XXT<@qT-4W!5zz{#t{d5YkyCTRn$f@eD`cSfh|=eyVN+Rk;I@c|2a z7pk;20Bor}o;)MFh&na!@A=*)ft5l_m>6l#1(UcdM)&KaiA2ceEu| z5;EVXC&1woGD0ao0BL{4#;#fR4W32Gg<&$(LK^SejBXgGw~&T~uy9M@3^pl|Rw1;` zN+~Q09v6+Ykp4eQK5`6%^InQwkyd_GkM0No=+8*2R8V4;ESE`%kPNuxDp6LDnA-$W z#=s~G&mOoXcN)_Z+^HdK2uGu6ohb`3krOhKDI z#O3S*-nJOwx;{Tg_e1?oHJ}Inu^3orqCWp`5`1|%EMK|e≧`AMm-wY5CMziEjz? zLW1NJ{n=W@%NIPv>g%;!c_Q56$pAh_$`tsI^LUMm4#g=;T0acLOl?eKX|(Jh$CIus zhq^o}r};y?n8VyJadxm`{6Q&ApWJS@!D!cxW@pgh!4L#nXTqGbt2B;ZEwWQ|HePEH z{pUE(PoA)qG@7gyT=2iZdYZyCKQ-0*3t%ejerm&M}i`-gZKM!waQ#qM}n z60-D#VEr)E=Qk{?lvA6+?F0=69GfB+pFv{@vx2io zg142JX(Jn-y2QD(3DHhK{=<8gC;1GqMWsCptOsf&?U^5*`)1ZK=6#0JJ2$dXzY?y(u>mGhqGXqBunj{DB~Nr;E5?XOG9a*wj#C2eyYV%6;Oc z6NI`9_8o;Dn0KC}5A?#rQs>5-I95xK2Z9Kkikm4r0Ig0?oRs_g`~#@os#Jmek|z;x z`>r228cp|3bne9m1VS>69O6tOi8NYmabq-wUDf5-5Yc1|YZ+dSXGwnZ7>HSAKQzjS zsIjOjS6I3pi}7Qf%$JAsm@7HWd!qd~bp3`U-VbOov)v$h8yiPXK-(GrKv(tLjor{>A+8a;eTrTIqJTyd0b-ftaEd;}sBMr?`U7ap zV=JPz-UYF;59nq5*AM}hRdk>~z2GpRK~S_PZ^3JJ!b0^8<+Pp%)ePoRn+1{cJ!?m4PIej`lql`yl;9D3DJt)O+V+K~^ z^jjE=a&|Ywlo_a6ttNe~H{|{dx@UK>Ld5!-j;feUYQC^&QMeXuD6Rq2B(jFaiAOW6 z(vV$L8gKlN4#w@p=9#!i?!`UXUJ*lPo0c3-dL7#;2$5bWGDap8YF?X2TMy_7rTJ!A zWNU3u2fy;p^Oj$kue zJYDyRRn;Sfx@b)yg^H)2KrPz-W}$*Ch!zB#=Iqhzg9=ka5on>XMSQdXJ$aMbUj%vs zskKi7u0ClD&c})cUXuN3sLRIi?oF`YdQE_t6ShKZ+TVm^HG02>YjeKs6*I7cuBN=Z z2~gDi52ED-0YPYSQ^Ew?tr%2$AwW5s;d|&?6>KxXAh`R9*qCT!25pAhq#Fqs`Gc@e zQP`nA^iY?Y(Q1PX7(S8UY*MM4N^}BU2gC1tilJ{zB|d=ThC%NxLe;1)IEKQSV~1T( z3o$%{;EX9#n#&zlZI@n*0*>)~fC6Ux`~km6*P;dHW3LD-Xg;_DF^k{RLgNY7b}zw5 zIB#*;w-uhqR{FyO0jUe1AxT6qB^Ih6>p&!}Dt|FiN${0YB`^;VOBP$LD+C}RuCz5F zAudbxfM}Hpyn6{LY%+)NRAZN!EMog>Aw?zR7Uh>YSTm1l)iNM~{me59mARLLJC%yS zn@QeC!}Z~$g!eC7T4n5&5c`&6x~~C(G721+s@3DzFP;~?N#!{LZ%zF}T_WJwry+W7 zGI-206TzvLSQy#fid0~_2a$87@(r+BV~t5^!s8nVF!2?H!7&_+h~Z}lj@*Y*h0maB zs{neZ4T1F6oXZ<7syW2oHiXcmaO1k!R%4E(+Y+si!i`~lRzo{?3GdU3Wo>zAy5Qt$ zH2k8iz6f#U%AWz&y`8@5Fl^0dX!JN>9z@H(2B3=V35hj38bKhSSuU}@y%y>C^J{C+ zB(tM}9h_*^Xf5D;!5Q5F!lY*s+o&MpC4}tj9cXrOnxvxEp`d<8$4WR9M~7B1KEfq} zH%q)+XLa!eu8_`$yt6u`qX|yf%@<~scv~$0+#BI6k%RbyH-qZ;KgR4Xfk{bbMebpBPw;itLY{ZR=EQ%rBLG$d`#PweSF1GZ6 z1UJ4rI6R4l1TV-oGD!$3VU+l4y;uCZIe;c%JQn zA?Yr}YJkZ>B(JF7(~9!I^KJ&5;|ezPq_L7(ncI1PGhtLOC*E=PNe(F(*UPJJgDq%; zb9F!HWg)wp-AHOpjFL5u&3j`sqz2-~p&3$ILN^vE5VRE^unFo=UwlB)JHy8k zoZsPc_4AtJE&hOljh3Up^Fhu**5F)! z5@*OcgzFCb8l586KxwBL_A9|So^A6043OjqhS%K&I4f7f1_HSi+9I@*;G+iO+_2F$ z{2PF-5r~4?`0L38YA}duX(YZ&pf4Gu7op|10EG``W{r>?{&Gl1oJ$i2BA!z4Tsk;+~6Fx~=H>EfDQUckFHhm}h zU|P@f9wCNarpE*y^d9XeK>UhbyIod5KwCJ?DZTF7JFT)sF``=d z5Vdnb&P*zx)Ijuw*gWyGCoW=TA25!6(dsmyLGz7_=8~mfdoV;Scm3W-JwO7~l{Tc;;E-Gu*A2 z>@Uy{T?&dJH7eNj=U1kD@{QzpluzBL6~sp57G(c%zV<-OkkxKt!_ zcRQ(oS$@z|$9%+uR5ZkUKX$5f@6iY6G+=bOjUsyq#GEhS5eRL()TOY$+n8oHH(+L$c z9UnS|t~jmusp)hh!V$m==sFH~$_&C0t$IyQ$JVSSkY4{3Xh*>8Sei*z(hMH1ka{Eh zP<}zl^8FN>B_<;y6W?W{MuA1~IRFrGO;PQn;~e0DY(0sAcq5K=>OW3WAD%+3qm{vq z!e(J5lfjPIX`j=6lXNy|7HxN&QbPnFtG^n!*!l}E(9WN+K%P{8m1bj=>}JaUg64r| zkTPd$(Sk=eAr|KhYZ7wJapGBOEwGY)a~#Ma-aCypej$+Uv~~G3E>;2Kf`a9(vG!bv z!xC+Pk`Tg_8|mh`PW+e~9~LEo=h0!WeMA#F93TqxZb}Kr5=PJfZTUIbx zrndH|qi`6|i^DqeJ`+u;YpCu`((?)AtzF=%uejo(I&+y4d#ROxWOlOVIo-X^%I#z&rHPMkU|;zPJa)OG1FT%< zIq;ajxtul^y;AF<*G(+*_-4>dHDBSVEKc3TXue&+)T0Ji33rJGpu z8=9E8l0<6=rkOqwrU<-+s!vuzgF=ESgFd(g8L%Dh*?eXb$l(R`^p-V1M69OX{vTss z9_MrQ{r|Adj#cISUG<<3`Ls#QrxYX6 z^_tyRfe18DeV13PxPsMS`-D$D4jggSCV;rJF;{7HT5~yD8YsMY6`xsGX}MPSDA`SukpBP>&}Adf_@hZd`_GGq4era3_} zannB#{J|2$if61reZCG#6Ue)T!}P^A$%$g_8j@rX+4S_4c;y!QI9_fU}-6sBR1ppy78BcV{0HDPs-7eNNxzgYb$Sc%f1gLAlr$G^2KEe6IIRvQ0 z2Bt08W%!#%?_%%>0SXa)HrP8{LvV=1FmZT;v{x#kOTLE!CdT?3X||de-`fj+D2v49 z1h=?ZY9q{uec92Q>=Y?3P(vKnHDVJ!AU#^n;w+_^p_?YZ-~+%F|5*7C>htN-d6CNba7cG$VpKc#UwI~zhL zqX&oShdVuvU5VKrMH_;+0obMAt}s z_SDz*&%{>*+x;~ViH8Q|=+mRz$OgU!XOYa^LHYvQm&)bg4E5e_Mx{)y=MdjS0mtxG zlo3(i;4ERC6DyVlesC2XJYDN2uMvoEp&$E3F9+*)f1!Xif=Bk)Odq1KoSSZ%^pA2= z;Ji=Y@b~E({>#g|?Uzm)o`zpb--whET-OgVq&BBvO!0h8N@r~-71>t_+GX& z09W)urg6jMR3hGaA z>*i9u3VHY_R}L2wo#2|oaCk>W1|XCX5B zhaggHm4pHgh`K-@SjL!51cyEnE;=5D5~|@5e!eWvf}$|lJyo>+7A7Lk5pW7}H#2f` zQb2#^P3*~qM<7KteB-+*?vf<}F8XZ_x6HlEq*2X@{{9P9%p&-Wqr7_he$qXHbvYIU zd)5UQr#$}V7&-MapiT2=VCiv-IzI(f_PgCLikl20QNi{8b-TmkyX2|_+16C&3`ochO%}?0K07T5X!=O)bD*7Df>A<2OzzjOyObC>; zld@rD0|CpO2NUbsKfuYSpR_N_lc{LG+fICPo8Z>Ee?f50ecAJr4d^p^vXS49gVP%?*6NN>&+)Pvz$G@VrrJjtxOHKDKdVeMb-Bt z2i8EN=iG?G`+a+`aB&~f`wO=Isjpdg^D*X zlh0jS@8Lb9XK??#Oi>Y*r|2%#e(DO?P9Ul%rVI{LyRQ(+Rp=1WIOSQ&yb7RhQB?8Z z+XYwYTdTbp1Z({im~GTG;K^zD)C}nrv=deW-cgXF^A6bR9%Y!(osw3!skxf=v!Am|^b`Eb)e#3W02 zBSVbyA;ufYx^dg&J$H?m40$okIve0Yp2P8hWJBCR@H1|ytuVBzxj=#YrrKXzYw|QR0cH<_71|O{`>g#qmGuR$N+ZdyfIKdCeutY<$ze?PpcLMBZcDTwrj6>p_7G4E?=N0VyFLMU;ay;J8(A@ z=*R7ST=%+b?=CFQ?TpFxXQgME*?3snXXa#Oq-TlLUWxMTE?4F>y!XTsBXa0|4TQkmBdfkXeB=&%l7zy<_;q&IXVTZ5{&g zN)MAA@sz{cGWBvtA|Ln(MtQ}>NQ257&i^l&1IR4Tb^A0#UA|hl_+L72K`1c%2ZCQu zfL$TtzHP)J?_p3#=btN75M!6dg@|GI=_B~H_#=uunp*`gtNn7HVh9ml$KXFGY4_TZ zi0&O!1(vFo4{-9gI!bzk2756sOss!EnjS)b>7$a_*&_d8cfEArL|I?(LoOPAXd+jS zy{Q~-Kv(w@WHtIYK5EW1H+sSK9UcOry(@|6Qbx#}TW*SORA4+!0!6$8U7!NJF>!v` z2;({P5XAG&5^fykEle#Yb?e$FnAB?Hgig#zp>Xn}_ySi`!7u53UO8ogk-c|rDK{ZV z?o-jVu^U%YF@DVjRCqTaDz2+miy-DD!@EmjVz|17gv2Vi`;8_xiNPI~Zb}^nZL|Ia zN-2YJ1t#$$!CoO4l9H;iE?$C|(yL|M)(&%um5-rX{$`vVo(c&AG6aE#c@fp5opC`ZAx3Wmz6Hh`p+^gM z;He+H6E0F;b>xyyWg%W8=Pi)S$g^*OnUj)>Z2>&&2Ai(FlE4ewyCu3l5FUh%LoKnd zu9pFoKZ29IH5^gDm7f2~h@kl|r-JMM;_Z#NNH;|o>G>lkxHbQ5U%FS%AIX^tDmm#HVfC9?>Qz5uOY! z6Egn0*sVl`v?Z6EO#n{d`|*YxGyeLbg#gi#v`k8 zvTug(Ww>r4q6;=Kv+kTkstWK4j;Ix#+I>!39F7D@@5nhi{h44cys7L0GED&!M zKzE@y;``kmq(=VyBg}D4X*18-{l{L*bHl(ZYYRI*dhkcg+f!%9Swlp;-L~3>gsWd-Q6(>=DAZ`n(n#B zicP?undjVaX`Vv`wj|&C3*AU1hHe$Z=+e_ocQO9y;jU6%ZhCK~pYVswQwL@{RO%yc zec;pRmeoVfVP4f>u_ z`z$S#O-eb$#b<$za;czc(sFr7lmcAtq0y-zD+_+CC%!&QRY~z>6tFtPa$^;y?85L= zT1EU|9U(AI@L!)B{OLLL$Nb47(=6Kf)8gTAfpY*4<>GVyG2nK+(ZJu8cob^DTYF=Z zy!3rs!raH8H}p=!vRc7)&@@^hI_bMKe4v5i(LTTx@A|yT*iafynW^~h{^H6|NvwHC z^hJ-6RRHqi)-caI@DT3V-tJ0Xnzs!0@Oreigb+ryAp)YbB~SuE0w@uK=Rn)VeXbC3 zvI@~643s?WCjHzlyx9~knpK62vIfF0xvi*bpSq(z5VZd#aO;$6)B+qD+`>eHBbjz- zF}|9c-T+hZYyI6(!WiIgAo~B294*fkTL!2lL56D{vv3S7PB}9M{>MW6JrLH3??=MJ zF}(&23CN?abJ!FliB@Gx@_JOZB>a%Z1N>ku!or27_&yl(u7=s8KSxxA1zf-Oq1<>}`kPZ;_ic)Bzc=*27Jgd#jdnC?yy9iGQ5 ze$t>thvQO+^!PR0Ms-xhZ(jiet2WGCPSnpyj1|#7aMn-iFlU1KfII6j44oxqxREx( zg9TnZ0-od*!`u;Zn5qg;#t&t#Y4D=EO0>*O33Am}=e`@}Mvl_$}AH7ts#q7f#O( zw2$6!%kp5mJcx{5UfFT z91aliA%vKnc-b9Db;u}hH5y|Lk`NHDY@{kxmk3iaeo?X-I9Go=DBsEhjy^TVQ(3h>-oo{-i(PjS?;J$q)lcnZh$j;r{!VZWU*sV)CAOhJ&(T6 zLefQog$G{7Ej1q2j0kV0N_`~8On?*kqkZmJ(X|1@2N`6!l@k-(VG&(WPwLB})+^An z&Y+5|^M$XVr`59|+1lkpGYw2Dd?E@y$q$<95Q6cm8kHMTWj!`=f(l-37*x6OB)~X7 z=EMFHQ~<7lyU&_N>(2n_D1pGv z`15eqJec8`(^ypnl2|(tUrl%C!0-kAnE%EPdHUVBc81$&qk~H`?R3y#7FK~H{kpfJ zlLvxKcr@Dy{$(rs>QtW%nGwAl*IVnhCSk3s!Yu|5L~B$f(>{NFZ?^kGF})4W+26j2 zbM~)oFoj%brCiu_4v48uTLP&=jaWAay=`hsd`UOqn2Wg&tO8o7-i`;RzMeQ2Rj0S( z-g3m&cA(|U1lnH;wuHOwK+8TN5faYr1v-M?9#o^Tzg3{>-uC!98-4R|D$helZFV3S z(AR-TfCBfqVER1w8zQ=+z4IP#xm|O1z-s(LNA5^9@h!mOWJg;^C3AgZ=zMpo&HT%` zr9oPGq@dK&Jb=yfq2kp(kPsVuOcI=5`llxtTWYzQFTe;Ibz+c0)TawD z)is^?$fOC%cn8&zI-?qe%yK7_2{fKSUI-Wl{XrmBs&96tqjaWTxvuY00o^R?@??Nm zkmqem9Bj@6-xUN;S_mFr{w(0NyFj*5S^;$65<@GQPBF6!Z$~*aS0ydTy_qVW89$V~ z&Qz`|vF}|so<_i}0VUC4ZdbHkOrmEBe(R%6IGzBU)Rk71E_rj`v!2BR4VSwTrl6@Y z=+Yv0>fCd12=ypXN+^Rnkc8S^fKhrfvKY^JQnW5YOsYSHujwYZ{CY8r^9AiH#ECgi zL4o7z;3#m4O7CH+@7{+NQwoP)wp}uO6v6pUZ-0W5e}>_|68u0nv`wK03~IB4nkc|o zs9_2Cxp4yY%-O*4G?7x$ojyY zmloj#Gncql`KSrPH7q4a=A(wL7bQye0#Q-iDD{CXoHO_0B1&N|%!JZPaL0}n7*O7$ zIQ#AEMN)(Uq`2UDD&S`Xyw5Rj(r7!y1=i{5!{?YGTYU^Z2bb%! zwvyVTRI$(Zmf}uzbb6&bJiiO3p_JwRirR9 z!JBC7S4losBQ{H#QUZ()Ix}7du{&BEV$w%6F1tAch`JGpcX?sBKnk?Jm>xoT*b6A0 zT#d@3FT{t;?T5J$m?CfK`qIpmFjfP#WkercRQ4sr)uSk87_PeP>j$iBRY!DOgE0z|BsWi^$?=To$|+R=aC~3(3UU?dXTbgNoq= zM5@GMmQ5$MJQ!GMDjr=fCuG>`~d zjYNd6$7#LRg9;HMdXT$<7`h(cH5%lu(KJgMYHXOc-m}Gslw~(dy_|*{R*H#cX+uwz zbcq#+1|Q=nd2$d@C`2ibZr#VgRg=LCQY7Q}1Rbv(jG+7a>|_G+cFaD$6;@#hb7$B9mx5au*|m^&>NaN5>31d0Q%r&JI-sanm= zh`{-92iX73VK{na$p9K0z1nOB(dQ+l#0ukFe3?i*O-G(h_%~q(2u)Gf#Cdo#H)D8g zA^d!}8!5Ue0WlZ+P6g$gBgQ)Q1roSfxeDzaK10ET7oaLpfG^kG_8G?U(hB4BBbI?nWaaa6HpgJQk7kbBDj+ujtdCar7+hQUS zDD);)?Yj}YlCY(5n-6WnLe(2ddtOaiEZqkD6!yoJmZc-r7Urtuwga9Y4MnZoD1ryL zFP>p@iSnZ%QAdno^;?M!V$5)UiBqFMPB~g+YRqEC4i4_zf$^vTjXP?pqz3J@y> zDx>En`I=^7a^pBu;+3+KYf-kN7-#MB1v&}htl|>_vCHMzvC!fyDdgS-`0lYZo($>k zb%@CXW3RSvoW1VZSO}Q;ha-Q~(_PRLF;JTd>wmx$=*i<>>hGY?mU zUFs{eyL~*qr=v7ay+45v`GqiNMDwS z+-(m(<95gFM!UfnxJaNX6InIZ)YbkQqF9D0PqjmA{RZ{^p2#aC9nua_We;F{!K3#i zc39~KUf%=0ynBzkt#~;}E>m~9gGHl@ks5`4r5gTKEXo5B$$S4}pcTIbXu@PWk9+M~ zjPvSbkfdgN$fh}SHf*kAlOXS(nu2ArmEaLuypBBu)m4m(L(HrN1?2i^SYAC-ZI#95 z@6d8|XILlSo{CMT<)jPub~S79>YUa1A?bbYckYzhbhTIUk!C`S`&j0yD6`Ag9Fy4%NDFtu}@2-dKS?K z-8F)I$PV$!!T(sps|1?-h9n}z#5*0LY724X`1=ia7E1>Z^VCui8}Mr3oS4KvAi z58K5ehO`O6M2lVkN89-aa7u%V$(8{*0a_C?Rwf}pSIfxThe4*_z4jl6%2dSh%D}W2 zXVI!?bz{mA42d5?Ju?d`BU`U{U)`hvcF?w%O}8#r3zqkl3Kabssu~wmGv{r?+WtT7!6> z;N}(Fi}~Vh@|kIP`O}cEHRju@B0scG{Bqh|FA$uNEgJSs@j^!~d;pdsw}aFwME5hr z5x(mTdJ1N}>1P3|_YStMAN^h(M%sC{IB)_iY1un8EwZ-p@V}&*<=@4|rJDKg;t-ks zGe9p9h%y&at;e$26GXcMxA~Puo2`|aZ0)vEiK;YMS3*ZLkakj1YD?!jwzsd+{=EO)u2YOBi+3au)S^jZP9Q zIt+_3ayiQiErFU`Mg#mn@ww%;ZBRLz%}bKVlxBlTG2H^a zq0V!n(-msJE;vZohZwk}`s^e)Pk7LWb~>na)g4|1gzeL!R2zG;gCn9*LyT*ZNKVe{ zM;uMU@Hg{JQFyKRmi*xwx(Z(Fyz7#lbnp)z!Bi|*z5-hy7G1~IDE}C)+rPCEc(Ld- z_6ChR1rM6-O*3HB(eyit;AhHXcl2LH2)0<&uT+45^3q~qWdr+3MSVF$n?F#%uNgM{ zh_oteqkTpNxTg~;j4b#z*M3A>LB&)#MA}ViuRMZ*5>^K*V^jd)6e`A`fJav14taQp zMKC2gN*GN78f6Z|BRSWQ8M5Ic$zW`V5eo&75Fu*)X~QBlBNjiGC@(ay5Q+E;oh@EV zD-A8NO;0GpL;nJaMXu9?%^#iq3uZA+9{SQcI{AAMuFqqlqdAXhSP6q3idb4OPigPyL0iB|E8Njb?MW>`F@X!ts zh|{nXZX*Q(QOopThIlB1y#H5m(ESE*i#VKOc?dq>nDnO`rpn9Q)DY#B_$AR2Xg(&IP*M*6 zoY`*RsEGa;6uSUUb|$aZJHRoB_b`0tV3;NMXMybcPbW4&44w;~ED!Grlh@(tn!$6y zE-Kg-1Cg-rYg#5^1}N}L?P}D|R9V6Bgwj+bwq&&{-4#?YYf>`sz83K%k>4=&VzIe- zUksXOCOJ$NfJ<;eW)9x7;N$w)Z-S^GGS+ZWh)I;6f_U-ZIsGeQ*2X(5ib!MQi^8pv zi8(U72q~E4#rO!ZDB3`F4E!zi0a2J>1a9|w#aeoGgDoJrd&vSK*|*cl#v9qTbZ=QK zg<|R{z%C_T#Vdv8$eUVXM7&|UoJ$<@YCP5~h^a*61fGHYAi>BN`QN!yMd=D?i`@~^ zz5^3%QNgGqe*BKa6YPEBYyx)gR~10EjKW9156Bs(s7UFi7d6Jpt^b}dNNde>J3kS9 z^I9kGv$K+tsBkI8$g*#1%0bP{W!FACb2*lTCcs=mMEZV$YYqbu>=I^8u*Y}yBLvmr zFe{TW#<54?hAMd=h{GhN-~-Oy(DwlLt`a{GVFd412nFFVf1qTLQ?&gWnZWBF4uEPwb%}7E{-W4~8FNG%B$qmO5eWJAWvM*2=n24`=8Q z(dq|oKv#Z&3Rahg&1=&S_W2(yN%#D(VV;!^EA@qr9TB+!{iT}2K%RS~rjijlVuoP^ z5^j6xxX-~tsSP2Q=$IA@5HW**VIY?tdM#!y{KEj91ksb|Y8vDf%hiURTy5CNmBBFu zVyg*W^1+W<+2I3Hom4c$`at4QiA%nQ+qQW?W4 zq9LZT_Qy1paSz?8VDmBVRcrfu30CQ+AXrW%z?k-C|D1XpuqP$5)ii#q zj4@3-8HA6vRcLBmlfrQIn9Ud(d0VJpM{P%GQE*B#SDslKVwuGkr>GTuZWXT+Y|wAe z%Lha_LrN3-6pL!QtUC}6ahqz8nHewhAqwWSVt(9WVKsv?Bz#-l$O|ZLcwHMWzlyBt zN_@uTN>wUAv0~j2VPBiyEgFBs$z>>dMi?bxkgf}j5k3?oQWSt-uG4_9I8 zIS6UXM$@PkCe9T8`Z*hgQ@RBTAYvlFdydx0BJ$AMkn4rN5I53CqI5)XVxV#s(z6F* zPW9Fkjic<==)YlnjiCQ<=MQ8c`$SSNpQ%>&h`{{^T{EcI7jRH_^o&RhjzVO1{v zcUp6Kea%r4{|EpFWM$OOm3AacLX&%rBy^K3jDf8ycyEM06U(z~ z5?W3m8%rB(bex!t&z`+Zn6W6}8o~Bm*7ArxMSfoEwEB9kL0Kz4%K^>iha#$F#Fb#u z;{4SaAr->Jg)2eE$-}v5IOENfFyW|c+O3uiycpPw6}Wr&`BjoJ2pHx8e@Jli8d)y2 z4L#0>HVRkb+RBV;R8_OQQ9iKHw6KVi|G&8U(ggqwRRQ`%Q(l>X|YW zmOHuR!zPwNPNnr-Q$E{2??IJs-nt{Trf3Ti+y$6Rx((j&@k3qZ)8~ zia2RUe+#?bnFb~qE;Y%%QV)%dy+zBLfp9_|>s5kr2cPA06WYqzslG1g@+VJ17wohO zUT+xmMXfx1vBMP~D(d{jUugb4*D6@}J0`L4FP;SA?P&ya8|bgTeVCimzUSUnL4TMX zFk~Hja!3_~iKDlPqO5}Y`MRlyM%+~RMGM|pGEUsMvIbHpm$VtJ0@ScA3~m0aI6u=#J9#8+`ugI{w1>&m3lhkpwj43sC``8?=ixlRj~R| ze765FA}0?#30yg;v96roOrjgf2B?+ssvu0PY{poH&4mjtTVFJPz@q|9aY4mCP_hcQ zV7Q~3GcQ0a1s5!DfX0jBr;s0ZYhvW#Zktz! zT;VdO?9;14uEg=CV2XSzx>Y930ApJ5+JWwQ8m%6~)VOrv$MI#vg;pl51nzHe=_adm zY&ERY*iweQbchEiz_(?^*4Er8d|dq5v}Uv>D~Vr}hIxz_CBttuqh)WN5+$~mHi&|t zL2$uS&51_00rUHtV~qFOP;(UA#-+QPqdC61UD%e^B@?WK3o=`v;CdN@Bn4Or!xpqK zaFOsw2xxAvTuZd)Z^!LHwsVz~mPV8~>5NYlr$S)@T_Q`>`ib@}X^_MP3kTp#Q?@;S z3z^2>u4;)cnPV>uH9(u08j%%RVLKgZZ`#6k$FxFAc^ypHh7d-M-7J6+sDzoc~3vN*Xn;%mmco49lbHP(>F!{%F@P@(Y z2t(NvxnS|1aDc+jSVmll2U`Gq1 z4X9bBGKaeocO4{A-fU%5qQA9O(5tPUBxJddP93nsYylcoURi(`zOw^5%5RA*1i$hJ zq{whVt&SKJpVwMN+wmQ1MXqB!3XS7B1q}izx(#tD8U`qek>S>!dmP<&jKO?39)w{P zYavbtrX)}j9p@QV?+HT18jL?ZmI%fwSVjfB{ND{Qm5qtNi0*`z7ao8Kt3({ln0yK- zaEXeiaA}fVb$w-l+>E%a)X7K{FRzAI?s%Mmq{DKzrHQ+T@W|hpW{Bvk7q7e^+)(e% zuwQ&PFCj)cTR)69q$7e0hpa%zG~e@xO|ZcOX$Rl$WaRikV%n+c)lN+qr4{*Td!I^X zZK-bp^sU zB@)_^5=FHB(U~GX?h2HoB^i(#1Y7h+LW*z|kk}oJr|o7W5dmast~8|p*!?R>H*lsU z44OBna$&ND%}ho|U7tcndy>f=0oOSO=@dhnA{4Z43V9+lD5)D-8&D2j?4>C{poXVe znVx_;y#@6pL7m83?0-rM6)mPzuI>N^MTvFrL9+9Fii7!yp2dOT38~_SgJwokX4Je` zh!H>G)U#mJoGrx6)bTe|eD5?28!B3MC*oTOZk6Gp)-7_~*d4QCzw+B$pr{fFbI)Ug zK5$`g=$VRXc`A)rCqh0L_D2J-8a~Qf4o-&e zeGXmmK|bK%r@czdt>+=f?K{f2KDFz(0}p0?dd}l^%DFO0pHt! z=dn9-`{ILO-y6dh^@S-irJ5!%hK2V7M#farvXfy$33f3UcCsJZY*(E~nrM*frLpEE z7g65}RGG-Ji0WRTXw~1CBB?SE>A=0D;azBP<^&?NKChvulHt<_Kn}m10XYnVFIYdQ zh~Y@m4aq}p7X(2NOUI&6K}l%QZwxS!pcEphsbqyd8LnQ1dLpX*dp3<;UH4sz@xU`%oqqpAL6#F&K*H=e2p;Lo?(oOWOwH zs8DWeVvMMg&IPzxqtLs6JGzLFpJ`MK zRk^B#Iozlw)~4dR$DB+S0#FYa*K>xWi+hKum{622-Y$B!h8~-fP*`+>EUGp z%1FK7x=|Pv|f|@U)VHWhuv#Cd7sa)_T6>tb^9IPj{g8SANBXWYi z==Bo5IFmzCP1AnufH4lQT`GdeRDxKhN{2q^Q~ID7M57ch7$%N5K4r5LEyl17$1?)U z$!xpW23b0SJyN0K87~PsaBUucxse7XoXJ5dpxn%CPB?=M9%AuCl@g09y@*P38TdAR zeIFDQy_3QNIS$5;F>D##ka>o30*PUxKrUp)65B=@b*!5i+;H8OF%v70oA!oS`ZD^; zt;=)-qM;iWB78KOSi~@r4E*U(f<--K$l!Gb9UqNPpMMC%M2`h9s3;U{_cUq+c6c}& z(`fgJHDiptSm02qI@bOci}!*w_+8y)^_0%VtxXw=4*1!q*!n~s7Tw&Wg5mXqQ-CxWNGH{Qr4CaDkUJ{>TINLr>~@%O6+Wj7fx5fsTb*4G}!2w2nRW*+WF z;_p1n_hZk~F;}zZW|J@qj!*0H2;kOQeoSz_SoO^#Kpx#$;C7s^vZuVt^0$eTu^rh`c~%oH}_`CuB(=oPNx-<~I#uLF2xMrG`%@p^s5} z7PWX^!}R!cGFTR9YN3ZpVsem?%4_0g5??{_r+dYXW(n#F3a>=lcJM$zw+I!Dn~~P6 zSE$)^3==Psgo-r;w^sTSg0sOqu{jBC7^S!!_v?UDkMz|ooVC*g0*~pbrS{R{c}saOUsd% zKBKsJ=M>-;;joor-CCe`+f5L|l2(LXq=VxS!U%r`Ehw{|Ei(;D1>|R!EBrUBy7qwOTJP&>RKy2;s zcD!{k`9k;u5KMOcaT+#lLWXsEn=0qw#9#0PRVJ3r1v{zWizk2zYos;j z14RC}$Xwc$*_oO6R}`I3aN)`keI&h{yczr|?GzS5UDxyLgqwbya1*8x$-GZ2Fl-4o zvB;EglS4epc2?4#ns)}m?)}9A=wY1X0QwytV~8cD;()nmwoxNmnx|}D*KyBO2xN2O zc^-&Y37vU2U3>@YbLmN5Z5Yw^cLN)K_+7wY+AA$OcVTKl!D1J5)0OWU5$RoUZjjT! z52Z!n5`@&N{Mxtam%hycQEnkfZ_!=|<&s@>W7G@M?hcNHy|H&!J85rNh^`M2h|YFA zUULy<$N{Vm7bp#r;Zq6D=erdJO4>907Qv&Rq8X6}!LX+m1IBV<^i#a(kP}qku+%He zMOhsDY;nW=r}9f!=d1o6CNP6u#_@Nv_p{(Vw8{RwCEe^3i}3T6J?2A?E)-o~+ zwP@i1?O8$}Ujh?b5L}SG6pCbb8a$~gT=!joL?4D(R2=p`V61o??amX@R7@&aw9f~H zGdshNG;vwpY*IL#E+t90#lb7Ud6C68M6BsyV@SfW46PzWD?}tcjp4E~!5>Uq26blK z({}Vk+Axu(uT z@>Km~7k8a`2f3MpCBVuLKqSmSK6#eUPB37fde(4w{j40x?Wl7~`E}42oRVrtQkSyx z*a^T#tDc}b5}p!8UqRSz>}h9=AuE8L)LwSZK4=AyP zM{bO@fYGUIZhvY-acl%%tu;a+fkIYu5T9QK^@}pM=znBM#i)^vf`PJITTKhv{wjV8%9N0WEMz&~DLS zqd8U;&QOmMq35s zy55MM@Zxr;7&+81QH%8oab}}YAz9xz@ar1~etF{{LfqPDREs|#3aFFA)n@M!|g95|f-J$Q;&S$sY~V_zriuDH z0q3)7ozZ|>%;WbRf%s;T^6jT*?X&r&2WPZaI4opQOm znQ0UNuQOqc`yO12@{)__HHcvyH;#B0J%`FJhKXNdzyC6hc>rLf0E2u|7h}7(98aXH z9!^bZh@of~Abv`P3qPd7g&)$gi62t5;D_9M_#w{{V&zxhgd9;-W&#n0Zdy3MHt@7K zDk^K`n6F6&orC4?)d}`Jc;jo}7KXx5vExtp;s2gsr;0ASK?YB}!YoQJ#<)jd6~NXa zH;^Rs5*aejCd}ob!ZVTde!Zn8eS_9=RNp_ zw^P4K_U-h=9x%7VT$f}GFH5bxsOx`Kixh^zA(QO!eK=}G&4`Z|yQe|bcx1m}#CWoN&?Pf-z4+JT zr}P-tJ2)%EH#B`2Qke?ud~x>iR3kbg*Q%e5w*a`l6O;#jO!r13@g0#X%}ta&Xt)#g z^rWU_O-3BJhT}Aeg~%*3H_MAh1GAy+&8+1xEH(kGa{31n5@FKJn&lH?J;~&?)6!x_ zDwG=7oP0y5XdL<2ovWYX?2!CiPn%bg@M1vcMPUpc|g)rFz-0*5CNs z?Y2pb#g*vr`c870$jmH1=IzPONXPa08%gL+OOH-JVEK%hMwxIjGDF*kSw6aq6U|uE zzw-wSnoQ^s8T90$Cp#AdimsA~iCcAQ9ahaim6xqxVllf6N1)DQ865p1iBT!9SVVbd z!Vh`o#ShI|RTd0ihROtnACh;8Q%7uzi#H-TF)v1+BN%tjS-fkt zyy{*BD6u?ER4pBmZPp%9=|jli<-Nzr8Z!4M7(@EcA(m(n;Ek-vrZ8EItc9QQ!h)Gsg+PtHVYU*2}JN{NDZ&zkPgeflWZ2ClDKU}4$=1)=pe^BB_zlLV%>$dUL$a@(VTSOF9zOE!OO!eBditj zh{02!jQz0CPLRO%jaW$OyhQ}1Tl0*pi|3)^)pk2#a2XKc^&c&=Es&`AE3nH~xDpoA zX0?cWGCWN-};SC(M)`54F@7hVKX z{~iL*LffVG4;DWLEp7{g)L2BN-_b^8*g69IP)z&X2+!>T$Fx$rRK9l%Qbmv9hhmCI zD@CKV)2xGMPk)OUrG_TfT>NM2Tf()q~SqDVYdkWh?`tln#$pGCfks zED+l-Lq~9~imwHF8vH#vk<=}1XkzRY!}g*akL1=Bj4+tIpSnu7l+cS}+mLjsUzxof zMvtqcn9>!F>MLjw=?Vw6=JZ$wJYTWI?$~lj?2hXb-y=2G>J=bk3mGvl0&%e`c{x3> z@x!!P64g1eJ70^Luo4>#0fQ7Fgg~k5AZ|XH{=U+t6=TA94F^(uRS-Q_y+Ir3R8kz> z2`MdhtYVgAp*oTZ< z@yrZD#q2dfd^zG4=JMB?pxyF3!N57}JLnX__At!i)lDhSd-gi2r)e5^<_i*R@LRf0 zTY#9DI4%5sx||oaK8UqH`4`$5v>yA~I%e!55GNQuyI#4;xQ+DNMpUxas#QjO>|%B6 zR($>^O!fF%Ibb*XZW|?JMqd8Jljxb1{l@8s-`6h28k%-bJh5sIEE!)U=(QEeJJ!6I# zvB}=p3;$sHe2MoQ;5J5f_8({*EjI@(VY7c_`UuxlkcPXeKm2Z;qGS?R&86>nHz}!>C$$z8?xrVIPN0uZtc?D|A6Ta<9Ej&w3$_^*17+fm5~eA(ZZm3HEG9xGR;PU{UN2!*a$*un zd%_RROr=$>K&&olRuRK+c^hpaK#J+gGZVY(^mY)i#kQuF!W0b8^CSe+l7;xrfB!W!<~X`>3Kc=$P3mwCupU)ZR^DLxHBQ!q({ibY@8cC=F%p{9#W zQek`&!PRcj29J^B@FaHtvVdqEOFR=|Rt0mI5MowKi$FM*;)A&u$e( zV5SifSSP&wT{_x}hx4*<4$Hw262FoDZM!3-lv;MD7#d+3v6-+dAV+0-j+u>^0Q}As z(e)CNfpBc9*8SsC#PJBzjKeuR6Y&B#U8Buhvu%t%UlTwUQGqGFVZOz6H$ ztefV-5#OT1g=I}w3?82&tBi+UU*iFY5`!Iqv#wJd zdg7xB*0FyONi>&&AnA_Y4FUD=0Vs8@q`|Nv`CkU+~gPX`o2C|qFSKAj@d%PB! zjJhm5-rQ$fd#4CXq1jMq)j#`~bxRc%$U2KV7BDDWgKXQ zMTYM{kjUWpJLHB65lauS08m>mob@agoUf#q$QbX-R5t+dL!A#Yl}p!`DP6h+qPo+p zT0BJ?V`qVr#Yt!sznmsBh1g$C<4O&qk}Ha+#e9)mZrpUXa7h-W0`Ab6-oes|8`!3~ zoWM&YxPfB1L#18JzC%4ZlywRg9q#dx8#H7W5l+$30H!#Quhn6~6y_%DZa2&@u{jGW z2`}HK!}jINHqj6#_^5n@XwKr+@0y^k0fUobDZk>Je*I`bZ$)0Ii8zjLkAeQu`B)HX4XK0=*g^Kiv7p_2f(n@CYWx&L zbB)tb00$X$t2zA|g0XM;IB#aXXOk-f&Ovp3kK6WaS>{%+R(#^Yfkc>L)tu!-Mv>8 zn2b3EH8Bg&Rzuy9r`Qpuszv%_UVPqGN!88nBI7jUQkBEP7)`-=Z=Oa&6#2;w z)u@4nI6QnuE2!@gXGnc#zZhwqZ&E2!Wb@Ah+NeYPTLT(&pE5|j%{hhwDXh?@L);h% ziNahZkiv=zD4wbp4%57BAD*=>n?rnA6ZqgDn)sh>6yOkbYN3F?2;?B*Uf$vYVlEf> z3+s4Usy4o0PiVVyw&iw+{#3yF=+<)qndJ~a65RL&Xwg>6QpmGEx29PGN=lZp3*v_i zEfJIJn1Q4ih?3^_0v653KoZY`Mg!iSggR(f8g+DZE{}Y49cS~^4<`HV7{$?={jFw{Yj=@|9 z>7d7vmW}o~RZi32nXGle>s0XJ@AkozLSlaLsLxDA(DRcyPzDe^#bOy_y@avu%>k-b zUNUNc2_iMbll@IcnoO9_Y&=UVSt^^pH8OD{8o_hyk*j-I(w#@tdaGiJ8^QmUZ$V|; zx4wd^o%#TQqMuxbBmB4*qdk8as#)njc*-;f|LDl219rpHy)D4H*1>zY4)%Sv$Jb1stfAAx%tM-_%8~ zxRg^yY`;d0>!o)FlJ{fEN&;jlxgR$t%oi&4Tp$R*9}*C zmV9Q>My3G+U6xGG5x}9k!q5n*A=qpfqq5!yz7}WtQO2I8iLg;g+366;dFVEn#wQTy z`s=WruK9!TX&G9sP{E=pl8qns`U@mvOv8XqE;^$kZ6fWZ9} zc5wj@5UEz2Z_M!*Fc zBW=3fGtw+Y0&8n!XA|>Unw_m2MYI>+hi{e-2A+THeK&awec(k41j777Q&H+G_9GRr z=qdegP=TWv3ZDB{av((j6A5;ZVV1zTMlg;u$iGjNsjXk4b8{5@AGWWEEX%1W?zIe- zDD1#&Qxme6FK?1s5uPO-n0a}kMJqFK^MYw&TPySvyr9)u69@;_Ip0zW4b5U^5x7nX zBm}TP|FkwKekM!B`HPL6%)k{SfW?7SBex_FJ8nLBs3a{J4kj|%7ALKxZU18=<=O$1 zSIQ(l4k8{{3OnmXf_-4YjuGtVc3A7U(wtfY_3F*Vfu?zTvz+K#+H5Q~w8s~?ha4gf zmp0R4RGNDm6B+w4RLE*&Xl6RHXle(v$a?czWhgNR5%0Jsq1OD_0jMS7of|?|&grnr z@NOMhW4_V}r?WbpO%qaRM@LAZgCRV6I4ikY*5jlz(Up;hLpeK$E?7VX?}t)lA`Y$` z@&sVTh=U6TQ32;i8WU#9;4_B*L~xD~y%n86!Wd^c4!U9Hl_gM-T zmec74xGBy-+kg^;e^-tc(ONK$X)7ELHQZO8a(&Ql<}VVuVN`FI2ZfPN#GrO#WObAavn9630AIeZ*bhmFt zVwZ2kJ7DQWA04|BF34V~66)JFL-Y*0MCGAY?}2ZE79NSb*;sTZHfZT@RE4bp7W2}g zXB=Y;(W|nBr%e~H|Ndb3Y`~@bts8Gv4`AY7f-j7>t*o;oEERKln5j5UWozAI;4|25 zWw%y{5j_$pQ3+fE+}+`4@Oj=msMQA(Xn$z9d}@g98g$955H236K-p2UG=`w&m+d7-i^i&){HEQ72Q8UL=j&bYn;fdski!jJ!y1AK5Mza zBA>`!C}1TnC5dTQlh4pzSTBC6_mw33em_YcTu8E$Rg>ocI&%n#EIKEf(w4+1dGARi zqGj4DO17gUwjoHXN{VEia=udb8OTv0BBp<^G40ydt{~wmgZN7?p$H zMo;Uyx&roZ9!iOjRGDC#&L5y8)@oWiB_(lQ6Nebq7c<^$!ALVI?aR(Z;L2d5neg_5 zMmWTU$TfgyKw@4$vzplBA|inMo4YC7ADGB?17vM5&n3#}bqAP7+W7!~6rWO6R#nOw zgm{bFy9c0vRh8j}o!vuQL$?w|I?hf#HUN@Pxhe32jgtiNi`V*_2&Tjw)b^Y?0P!Ae zP5Z3z1|S0NF+t+UZ7(4RCL)#RC^_=!fhI?1=ZkiOfN$Ku2EJwVlnvhvn`1%wd8D!x zX~-FrN{bj^)xns{(2Cq4;xHLDV=!z-E5hUHP4?2_EPtTF%N>a_3%;DBj^E1mW{6FL zftHE`iNyVMs>ZZIT&i%jn0{Z7T>0hc70`(TTPw*x+Fb9s4=DN?l2-rG; zS)>zgUFj5=Bg{&HAn0sd*5n}Qr7vN-N(LaWYT5`gbwF_jFk%F1Th>jsLYyNIA0oEY zGI2~rwu5z3L9{JL0z=JCI4X#WwUy{+_}SN>vOzx!7jtS;0yEmNT(Dv!hR-|p@7j9D zazUw4=%Fy(-bjA}ExZq1VP86yg)C%T^~X_YgR=_w>i}IE-XIYAm8~+E`Lbp38dgLH zgXL(Wk9uJs!k42ig^D_3%}RmeMh>UT<@Y$FGB9U6vn0Du7>({FrDkYK<#COn0#+V> z&d|yu7hL2o$ez{Q!$b-Vk_+08A#9M#VS|Ua6eJ24Y#n1(6z)t#j0_q~?@IFVe=@6V^4 z9$3tyk>B!?RN4_~kWc)*C0+JVg2rMg1vI5@?~Lv&<~N zABe(2r(@A!BCMX^Aa6I1d;JvC6_0oUEOsW|den=Z=@o;YreRu3?VL*D^LIx=yj*Vz z#MbK#9^3F4s;yQW=~;-OQG(oZ5V2@gtvJG$x^O+YH<2~pnH+-EwiX+isEP{WQdpc| zd@kXehK7jOM|$;QLzgHK9-pF@8)9*q8R60qdq^EXM2~%{&38Fj+2Wz8EXQ+n#5CbK6r?cSG~y8`NcA%0%>mj1*sbFZC#94M5JL{Deg7i^DBA6C6E#H2t<2OQt{*fj z@b(W;e$sMpC{iek<CtYrt&jAkih?)) zr}bGs)uneTEYsLAYJqgvjONMp=FpCoJef&Nt&k!$izzQdJ;jtcxI;7L)KoVXQm;_- zT-3q}g+}^7IGQ65ek9q>kw;J^M1zG!^0f-$$asUIVONvyVG=G4>j?^n)c z3Rwo$C6y`b!)dus(Oq+Bc{M}yf7`~Pb9^ith(jZ~=0JBaNsgT1iS_Wt>y`KT z<>e!mpJ3&W2l43U^R1zpNs!Ae*A6}8Sz-%I3KZ4wlB)7$Yp03c6UOZfL7~w%2r^XXlzX1LH7loY) z(*j=P9L}ysth-o{V-7oy@urpMCJu_&zctJ7nLyNk*JilmuJ}H2kiL!2X4Y{ViRN%=q>8c6c-koo&K+7 z?p_4ZIQ_l0 zQ6O9&;B3s9IF9-3qnYsmM#-6;8~b@$FqQBy?@~drg!^3Z%!gDEoN%8DzNdmkA0>wc z67DnHyFzzywJwg5luVl8MZYFi60hS0KTfC5pvaY|`d@PGbK&|y*f9BC1Xb0pM`k?= z{vjGTYJK$Gb;^&f;SaBpjoA|JbNy8WFP3nh3lcuky$2HRbHSL8Xvu~os&@baS@*g0 zQ|q%p)_pE8R-?WDmUW*?r&y(dtovMW(<*S?;*9m0qPng@dx6CJT>0nsVe2WDc%KW( ztksL ztwJjUKf~L9svEO1@H71LPr*NeGw?Hf=4`rEyeO`Wurly7eAX%~77yy)J)KUU3zly{ zLoS!+eBN zd!BtR=)4v9x}Jr6`c>PIu~M=|m)NzHFdv*}A0N0x`Zg>Wm~WK0iw~ftP{aon%%g&0 zDfYSGi!L}yaVGuzWEfxf!Q76|piFXUzwP*p*?+M-`&@d&Dm@*FZv%Puxio(VzGY@z zEYCiduCPi2dG@&=z6iSe(e`BF)K`K=6#)%ao_#iko+r=;lzQJ1oNabup0ORtDodtL zG={|4-7q^AvST|2iR)%xK-#|f2b7moaoE`1|Qhj-AhI(l7 zB^v79iAS#_R2r*OtYYP=q({D7eQzAdVVV_R>@;6~3^eXj_6y|4R>Z80`;ipcAhs z`Wg$A)`jN-OI3Hu+FN6{N$Kuteq&PF&DVC5PlO(q-rYspa2a*?cLQ}l)kH?9^se+h zojQ@ zcZiq1wVgY-+biEL@EtIRH~S=MbFJ;)p%$C|zbjPQ8NtJ?e1&55_dy|8gFRqa zL%M5f;zp1P8hXuMTowDdJJYbnMwNYNy>SnFWt*bu)k>pRD~(=tH(H$8hZSUFd$n;| z=jE>2@5dCHJWYx-Egr+R?#HTDcOwZ58{0QNt&QzmdccW|%IG(rv7ukoI$(yScfsya z?j5hbzN{amK#`cH(-BqVk z=O^($EG}RDVAd2fdNIm%{d$K{pZCN4UV1+;Zk8X$2-z9l=Q$>OjneULapvIt@WXR< zY=*N5lgE1Ss7X&MA3uVX;tevfw|#@O`Vmd@2D#GPzCkt;oKN1J`#_hrc1ekb?uueZ zA2gvih?siRjNBM^452;D4|v3Ne=-B^Yq8`fnpi(MS&2?j_Bded;LPYxL)Y=9rSKrV z*m%MWyq<}SKD7`n+n^8LYB}29tomQDnRf!%d}x3jn|PO;I2+^O)(Mz?8L@#kFnE|R zo|K3U6?F$P{xo9OJ!e)D@vHfXHqB%HI0WU4QCN169fg#~MhqE5(n4>jd8g3saROP0 z`*{gOJe&{zkFWQD&Z{`yhY!Zs*ceR z*`3+h+1U~9pp_wicfL`z^+Diof9cr2chTtIyTA`y*c*KO8hh^o3y+?wCkqb_gYgXd zF!*x7VZhv1>=}q;@pfAb;Z4lgAyg>w-kZQUy$l_(8U1SQ50{~P33|HU1fzVo<6HPp zF3ZmwAk)&_QZg=js|qpqfT9W*H~&vne8KIbx4?+PSjjsIQoiMFR209XAfVsBE&e+V zUiRTxC6Q6dOyA;q++n@qPr!;tE+g$33-{Td(v!T9?i$`xkk~P@pdP$BSx_rn?p_?D zuU`)DhdXgttcnD1sc>&ah>|RE*P}Hu2jSEv8Sc-JKXL{1e9552TQVMc9WR{79iM-# z5uM#qiX|ptUxfjm)@z0;PQnRcSr&LP$BPL`-^D2 zctk=-HHBYmHdx#O3e@rw7AR?%Mx~n&e1(^bl!EpF^o>i}8>vy+f&Hcl#R()9mav z56N>=hU3im3?Cgg2Lps&H;S9?Ur!v3 zANi6P;(IDOnA&sKg6jKHD~XCnD05_)CjQ>c7gZKgC)u7h~PQp6QGjjmoq*=cOE`d zx`SErz0091en8mVvp8@$z)n63T|DNW`1GkxIJtc9EH1%uFsMei`R%FG-BxE;?TnZc zIrrh;C&EiypRSNDeDhybe58Eir!d6ce>UFm%43}pbiVo&b?$f$RdgTd@WD%A&%i^l zBb+-2%{0QFP>R0uFQ9bcDC`%8or@{dSTLXQ!~cycs=kZhr5)#D{1BGL>b~>e_~4my z(XSYGV57v#BT~T6n9N?(0ExYtJ8XTni}SHxeQ9K`cNup(RqcK2)qjXl|csKjf&Z4eg@W?g_K815oU<-dFZ zWG}veg?)&wMgIYati9<%&^-phV2u zJAQ>hf8%0hW@Cg)=E14%fJ-P#J#T#R6`GS59PYS8RxBu*B=T+`Y{fi0G1@ zmxBaNyA){G!%Ni${q~PA=x=Vu`TWUOa*p^PvhF?-pq;N|UvstArymn` z*_9-Nv_z?8S?yF=IM@t6@_|Dd#>y!vOGU4)+pui6s z74bsLywTDASO9Mu6-{)f{|KRm5D@JwtRLd40;@urJ-|PsaffGN-DJFW=!fWq(f`wv z1x?V*Q;h;-Ov01&pWV>WIs5ve1PoYcM*g1gC9`4wH&waczm(&0fZqq`iET4jDGIc@zJOT z$fHIxgF+A(`MoX4zfOTNeo3;kRyS@!gs1|nbmWg@s6BpXOaOVhf5ef>de~nl0D~8P z6!dHk#48$8VtJR%Mt`E%s9IJq{)^s$Ea|?!YQ%Q=dOjt<2orc#0FOqt$r-dK*sM~t z#D{Fg!37QH)No{KtfP-v!Og#?1Wq8f$XtqYB{^hetKgRc9~U^=qkvbkf9V2V9aVpk*9>@(4cLfX7C@ez+W-FL<%j}ei!_LD9Ud?#0AIJ@&nOp5mLIZQK36CGm2!;08JA<= z%FL7q$32sya(C_d6Nisw$dU~Giqy%@jlW>pv@H?$R?DqpIfmJUA0RvqBnk?gO1GFY zwQS2;xIar}e?p;BT#rMEto+4w2y~^W+)Q`gM`aWF^3d?Ha4$o^e9&7$jY1pfnmA2( zQ0n`9O0{Edv+%kbnz_T0%@$@Syc5?;B z>u(j&qLMlks)O-L9@oJLa8gq zkW18LqHRel%t0A{T&_Mf8UJ$8hbJJ+FuZj@ECvk{uR(YF4)h_Vxk4(#(Yz9DRF*}> zIkfi)ABaYZ$jzm3&y;Vq4Wj#Tr9dZPSx6NchWZ|#9?e2T2>(zCe%NYS@b`}jdR}#+ zJ3fkbC`FVmkO6~;ej<1kR|_z)tPohtr0J(3Uhd_jO2m;>`FOpcO(Q1?1WAbE2go4CqVp*ywFCT`P%~Edk zjA-VzxClsc=z8R~SXN5ETL^h+ZeRwmTG&-Gd@QDd7DQKAkrWi6F9lzl5iwN8ikVSe zaHw`0ANz$*=6`t^gXSB10mW^e87NUw!M@v*AwrjDckA|8-)kShrR`6DMH%O5Fm(qM z-QyJ~NX>Vuf@D+T3}##~t8#1i`#T{nVMx|qd_efzUqd7@YJ)U))Q$kjR{DFt=0*=Y z9tIb8ckKv?cG7{^e{OvjwG8-r*S-oZV@3^d>AVY7(7Qvb*jN*7?bfb>wfp(IWJ`fM zBqJ+Np4_c4Bjm9=p}iXoX61fEm>3Mp?%}4#SG>!th;}vqNQ}FzCRzyPwcw95Z<{R= z>cUx+%D3VL-YNI;ATWn871Dn5*Dz14z8C5SkE8^&d}pA)nINjz0(x#|Qh++oVfTT$ zF|qcT4fsWqu{FNyK2bCM2V1-gwQTzRti#XZ(Yv7RIroDqyj?BT4iF@<20yzW1mq=I zfxk}p*FV6ZEqQ=&1PvAV{&N6-_yN(B`Bpm@$%lSSqxXYCz*>V9G-8_MVGrD^7~nq9Th)(;+~rg6%91Ch=y*)+-Npuw2zqs z7ZTNv3VI1VR!{H>(a9CKEQ%@gFz9jH+-T=iC!=eMG4`K9=(EIQftJB1mgw#tE`7nfjH{M_$^wQXd2 z2yb|pl!kw(Qu-yr4xffS#g8AxsK830@V)bZ<5~}54?p7f8q$rMnKAeXhlVGx0>euv zFy%cWl=ch9>bj`f9rmbKrls7Qb@=w=1u)9}`cW9=WM{;TQ4)w+r0U$dXb(gI^pBL_ zhn->;y!G>@dT{;8C*Ype`H$(g!@6DBfZFAH)W07?x8wc6*$tS{<67W?c=F@uBF*)J z%|BRv&R=l#{&B)#?Nj&(jk1!}&x?41c~2vn6NByYCs2yJQTcjq0bk4E#{6~BR_>)I zs;ZMYa0N5vBHiw|J5Gy?wYlZ4pvv_)Axz4y*cD}YWx0-zH2z4q1ms=wdmRBA zvORZ0#;dfoi%t}Wb~0^dPaaapQmg?M-D$fQFU9}Z z9kr#G;^X%KpY=Y21{#b4qhjYk_sL#Sa-j#I2v5EUhja7$aLv~33EEff7wtSkuLHTy z_6!=keIe$0*Zi=t%#i>+PmqKxI`t3U1T1CeFF?i{e~_+Y!y~YtEI<|$KZSw9cM z{XLx5CGfW{$4>pD+Yo|ds~5o5=!<>u_`X=)Dhrk4^?i)K7w{D$XGm>Z?uS;Mdw~R@ zNkw2M5Jty&x6g}|Di|-qN68tgFvL!KM{udZtAFM~bLqa(?74gwQ1^ZKp=%I+=md4&6X|Nj}}1AtS^Q8LIc8~~2GXfvV?Kk_p9 zJ07U-kDpQ@)}zcTGERO_AG!d`?WR}!DkFUrt0NUbInJ_{9IJTRJFj$WJH4L^KmExw@J;$X~u3541Bnz?mKs{;q4Hm z920vOwQAsp$d41r zX(|U2+eJ@vyN&K{SQH^TCNhe+)~&o_O0~NOM~7nQ6?&~b0@zo*lOpTegq^1_92`lx zLywFKdM)U!BW+O|r^-Vt_zMoNlh`dj_By`d4Ti69Hy;Ji*?-Z7>f8!M=fGB1E}LjK z>;^Spe)`!BYCwuRl6es(5*##b%70MA`^?gS{346}ttu zPMW?Yt(-#XZj>3Ht*4EkzM%IT3yAeP{)~!BZj^O2SOzy?vHz-->E;qr=2Go}vT7JDx(h20;bYq3-!EcQAv zsvL)G6w-IJ5#SYlf<Cr`NK zu+4|x!R$$uaygJhTz?W;D#%;i5`wrc&m#JQ3oUAb^!u#o&HtM;Vw()E8zJ&8iQu9( z(At+7)yQ>97UV5Yq>a8%Ywwf59VW1%V!?vRv)V2Ea>~fzbs1RV#$SejwY9z;xBbZ^ zBlhdLsybMlFk~c?`}j0ifs(Pm=wt-2&EZ8N*L`fMM%oZeKL?yI6=4j}S8V(texv&; zFy6dT%?`ITqc7KfQZ;fku57~2*NDq}?&Hm+2}yn*m&i!uT`6(NQF!+zMsmUTpedhR zK6$Hc)Ut@P0o+i1@ZhOInV&Bq`CovA2n0hNu(AOqTLO$PbK?55W%aJwdMud#)rM4MPvZKz_y9KY4Xfd9UI)1->=c^C-_=oGKo)xkhf zkB7K)M@HW^4`v1f!G$ zEzZOICqavaCY!&7fvi}Hu88K|^uvmgTY_OQL8fA^A#kdb5(u$axgC}TnB9c^Gf=k{ z9f@m8V(yS4!{$!mq{ZyAGSKlcMpBWGgQZ3#=j->PvlXN9(6CVfcT%{$jMqaNqw!8X zP1ak?g%LwFhgWH2;syyoutCC7IKs@?GM9-)O|-2PPfAXR~Sf0Ytl} zH@MQ}y7OmTwS5wpVHua%OO|dyHjk?9k~Lam;Xb3j3zcIcJB(%cJD7K z4agG$+p!a{rw@Z`*U!JCqDR}bWXQWJQ~sN(;H6GfdWOJIP|6L12LGMTXx=pR!|S8= zut`ilH@+7pkBi^O^C$;?MfEvueR8)S?dfM>&Aa<6iFJd8UQl@G4$vCBFw#{GkFX=f zEYS>Hh6f&BQxl3|vwBb!9O*{5kG~ep6wCaZhgMH>-|2~_Uv^BSzQj`RS3ObXWe-H$ ze^@VEdoR9z;1=v#ciAGMf{(8^PsDR}h^l=c4&rWm8}VPS*dpR~5m|iYh}`htAS?-A zZNaK)agZpruUiQswGRVKiavPeVE5^>mI zl!QqG0vaCpkpbOJ>@-0iT}e)~K@B{elDL`(N}C4RemE00tpY>@+=U~eAg)ULDpdTB z5$F$HX5{1NSoEil;GBEO$cTPCxL+X|d#nb9A08PF=?w(cZcU=c>^@-)zQ1DYNY!uo z@>GH(Anxc<T|B+@@+{TUkM zwcC=W9<=r}9LL@Yz8||CScG0ZZ>+$4dJACp)3*@;XWe!f7V-CxDh@pz^g4ELxBxtT zE>&4jSL)$OwR(fG}y|nUu9#-w{971a? z<2Wa&#R+QF>j9g;2{FH(8HeeeWNch7=A=_Lh|TtI>#?P587~CIRz^NOc>{Vi>p0kv zpBx`?Pw6ur`V4b_`rD;jjj9tR6rMM3(aV#jxNEnZy!9~8#M90IwXT~0y3#BlHJ*6} zkP&0Tb|uj)F?tL9L&672KqlHR1hn{@0EzwLEf%HyLg3BgVQifHJnR>Tmx3#4zYuul zNvxQ%&$}}P-}PIl2XI_tnHZUmj(qSPW{8i@c@r_n^t1xJpzb;URFI%u;o8rHSb=-a zNY^xp)6wQhg*#$b7_ELY30;Iike^q$d1s;Q&=m;qm76SOK^w`qo*BK@VV%8lGCE|u zhB(zVd^4KO>1B^4s7$$fORT<$iWgA=!nznnUuXugSl_%yxW&L|7k0@N?B zu=IWp0`9#sbSs`K*Srez(3tV1C2rxgkOiK66)pU=b#jTjD+T|8@OgXUY_|4bRJLPz z$RERM(1{DnQBQ-{g~l`B_5256O#Z5zd;n{b^dQTJSC&*nJI8)2Lj_z*k11-${GgB; znULv)l2-{cUM2KzzMza5E%11zt#=wn2_s=QGw>s=%fO>l8+8Y*ubk*z)%3YYbyc%x zB{5$X{T4RKi@yWR<*nJDRz|SEp+^GW?R8M{-r;!9c>HwFCX&&?j6)`Y#CYacS1-ch z<>$991w{gy7A|8c;#sfhArv?v@d}+)O^;|tX}-E5}`*&?S(+^9}DRkAreaS)w_ z;YpORBco~Vv^O~X`;<;_>qp`Zf-@rwCy!zT@tc@=s6$+f4}V!rZg6Xm)%#9xRwMLuQ$;fzP?B7!PQxji>WliaK2r4wSin^5Lsyzr7HF?#dyHsv$iydA*) zp0pecMp%NNM-aUoD5U5zWaA`}l*IbD-HyRWE_xNB5Cd|A+rP#u6wGbKIu_H?JV-$dPdTpw`WIqwLhUJMDj*=9 za`x5=ATlNiuexXdfRo#8ccQ4HCSx5GrF8X9U>)BFvdQ~&8U!#^bc^#)!NIeNic+=w z^;|_v+#G?#_hCo6a~5eVQ%>)lSqQeEUSPNlWmK) z;a+@lC1%DhyT}AUL__K2$0OhgCNGp;wu|fnECaa09*c{hAL8NYE#|01vu}2P2YtL{ z*NGF{+zVmVUp@z7)YILqU}o13K{naaK9~A*K~|!1ij2#86%x^zI0G=LyxkNLygfuZ zn~Z;frt! z{4y6VaIWHA;BxO}l@sIyV`-i%1H_`%bucqe-8^N2dn^z28KyU#QLXx9iw={$NC;;K zKPYxN2oSZL;D_fxZ!*q$ld;`G!{8Q~jI(a@Pb;eB4%@YLP|(5!ev8GEr*C=)M^9VU zqcic8B%xM2_drM}Z?J_cH);i#8x$V%4tPyLcGBh0%DrJ8xGky;Ls+>;Jxw=6C-O6tvqm zzLSJ3LT8C4V9+xQ?EVD}g^#vB479=a!L;^7d9j&X`U#t!mV1O{_i z9AT^Ga~QlRx%gM)#p`j#+Iu6G(@pb3es>$T2mk(ae!3R9y41T0&Hyb7AhP3S;kCa3 znG=ox_rAFs2CW9jE5gjdzHI@c!)Om=Ccckmqq5Y3y5C{8a=1j9VTRXPVuUE)>QFn zg{;@b;X2ATk_F#Ir$W~mcQlax!QMi)L_lqB#kyWg5j1k2a7wxbcY_&L>;sAh6SDbY ztkll|7%YH?eh9LZ-veQ_$G(!`N9>djRTP+Q7zp})`Heu z&i@ra7+IKXWMuFC2wga_ssai(E~~g558$S#V5`Q4qrv~@9Uve0wPNbW_+XbWpt)T9 zGMMoTe2`R!cA?Z`r{sEnWe?SL6j1yp9R3^!()9h$u87Jht zf{jB4UnVV1Vfcm_co^?Qbz;T{{c;*nD5T$i5VXukQxh8O@(&K}TnPor{msx-9P7be|zKyef7G3 z&buz;)O8_dXbjuv+gJ8Eh`!L!%Xapi*@SG1vLnbz0Ms%-r>WX)P<46)lT6W}dIyZ$crb zig|*cd$1-59?YgLTZzkBX&o!4*RAkoW3Uu%`zesV`O}gTH-9;}@1up#ZTuv4yD{^> z{=kMjk~b<*5%dcgTretb-?e1nErCjL9c{FIaXS{H5Q)=Tw&td&MaGsd)pA z+OQUjVtUf7oQJ*8r$=+p{J#Bf|CZHI-y0$p7F-`ceCO2_H0ZNj*}@?N46Zmbmfjxt z85wq6Y00K=oR)^W7rv2FcrsHkLc;cY zFQx>fLz}d5$**Y#I1`>6KUo}_9^`$XamP}~dQJMo&w7Vu=&xbvCu>Z_2V zf07S;-M=P$UN0sbTt!B>BafqA?v;3O)h?LNcOHi(co)rjfa_W~rQM8(Yug`BCB`d= zI8foELFXS20{M$p7{F_P0DTZ4(MGuc9FN*#(nVt+>cmB$?F8&5aCq-NKCh%~sE`wb zu`-F@uH^i71&`6%^suY`g`C&s^(7^arPtC$pRPB`h$1dj$i(*U2GvE4~DFV{XUVbj!&= zBrbnB%U?4VCQ7($k8tJ9A~9+ERxZ6g2aGl}2cK~19DjJ_4EIqpmN1X!P)?Lx9W1Y8 z!v(?9&s2<@SF&?n$;KM!%lHBHN_NgG*|3jU8B?+g`k+#xOCcI;9*D006P$FOUlL5T z@?5eVKrC@q6OST901fO%w{Q^rM1JMJoCsH9yK#R@YUYgk3K_561nY;~`bWt7K!&=H zf6EYLhhf?O?ol{>{cdXn7geuuZMX{D@?|TU@yiaEr!kmP%i2;}J)SZ<1RBaSZ9!4D z`4;qS;hQkB@3EAp9k`XE>p{iW(WphogBG5GUaiGj$wn`)*6Qm`oDyEG#T_nRM#d(l zid*mqmKnVCGu#bZmRgwBehmt2{0xfr;h$lR=w2qg;#ZLCeo8c{Uc88mEiq9&4=p+Z zRNk$feM*25lHk4<1x`CfT$@;33D*TZw(CJs-V6hFA=&(M%$g(@r$`*zuT)!+%*@g=(I_fwff_%)mz zja(7n1)v!7SFR8h3=S8vg5%YvD);INu}An(ykuWInkHUk2X)G#tD}2h-rL&IJ+Gld zVYTjg4IQ_AJj8ccmGXEz5to=o_^+43bNb6pN@2vLRdjY9hJO8Z;$ET+E8yW7zIZUKFQhgID$lcb_K|`7nsMD-*vmi9f{6m~ z+Hl}o{wo}g%J^KhzEi%%t(%l?-5Xd?($rIj9+@4X^>P ztpF1Vg7D{oaA;fg!6zk$#jHY~{iylfK;Ant=e^@d-doD^UO&ebFB^2#&tsD1o!Iez zJ{T^14{XE^uVPhd6+UzXhwMId_3TvvuennQKXD~>ogw$-t2x0yV6l> zWlmYymb|FkN-S^u_wQpBz^}glrgh-Xo`=}{&3pT}y^{q-Gxuii5biQBVTFEXt)OjF z`Gb+@B5d|%n#MheL^ivrTO;$oJ7WF%{yOrFsc>%Pu4N{)#-D7(!kGIJ-LB@9tacReShSKbs(V+Xy58z7Y z3qw3>@;vqg;qw+u!8~3ss}-D$gwZ}{#x2KHl(-uuBVJv{^U17|4Z@XX;XVTQGr>C6 z70*syJqU|v1Wdt-M#{jwHTC%JX@^akQY-&^9u)u|Uc$^0K;Wtn#dR~Fw5 zJhL_3{oo98l(+0}I|dz?{Tqyrye(hyO|T&^yGieMVwHzjsY<>Q5rs_yG&z1 z{c3PW)yU=bZvXOE0dCAb%Tv)-o-)Sy}+HEEqt( zkVVn}S$-lo8z2XOYP<%>6ClEwfT1R+D})G{tVlfpg0TS_2ng`3Z6qMXv_L?BDiKq? zQ>(}jbu|PVKuQ#bNM3^wcU4FYK-^U^H2`r}1=RpVU2V1oAnK|a8i1&)hG+nyu9_kN z=zoT|tIB9aWFXYdBZd%v)gogMdSI_i#UOOS-kXX+=!CsI6@$-UNMPG>IRb9kGh@V;_LeawMH<2v&lqsit56Vx}5{0f?At4hA6Q zRD&=8DL15cLxTwERDbXg;-*T0LWqf40WHn`sg7U(_D_%04Iotne4A(YR4CUd|L3LF zfD!WSpGs+~g#A-#Z2Ul9%UPVxT}0M z0C87im;s2o+QbaNX4E!j0HUt)$N)rL<&yQkj<~CUvLeJ?Phk}xbp*4ko@7^hkrg27 zD!&Xs)K!idfT*iHGXPK@s#AlKL5RB=mJGmlRlpg5xT`cX08tNRSUph>rI>sX41WVr zSNlv&M%JGO;;x1ot+au-hhnUOxQAk_fn-m_SW~8fsE1OlfvAU4tbvGxQmg@}581;m z)-G`m#TYvmim^uG9*VI>qORr?t)h{rhf=JOsE1Olk*IqqCjD?)7S&uoA%CoQg;D}TS??(a> z6$W0A1SBd9ydeolmQ;8}5>S`uAMmCmBwFBs9&|vTuRBf(Ic0fxLnz zApr?VvqUTqS3__yBqTsJBSivKGsInY$=clvaSuclTo4HeFwGG4Kv2Qkgn&d&!3`0B z9OR$Zzp@$P9!M(q@(~bFm3Rbl3X%T_2r!l21#${j1(pbCO0A$ikW)i&0wg3LYL>VM zf(lN700eRhj)w#UM9mWQKuW=%j(~uuY&MWm*fbDOS2YxOKS#3bk&058V!7VL6ty&* z!4nW*O0irYNGaTg0U(f4FclCGV45T9fs`78TO1)Fs>D5zQ$nCXO2KW81p=bxiFzQV z5Uq!R08@(G`anv-i4FirsiglDx%GjVf;Sui!SLsadmyFY9Y;Vg{&}LV+bX4@)EQt} zN7Mr;m4*ICNPub`aSy~4Hr)UOQVQN@1O!B_V>5x2f;Sog0Zr?OdLX6Xokl=7{&mDX z*lh{dc`?P|r^u}jq!b*e2ngm>Jy8#&6dbAu2r#WD>VcHX4%HL)Kul%piF+WX;BiGj zBKzTaML1j;>v>wUjNThuxhO9BECs+lz z{cQ;46}M*%!Nw}f&2K{}u9`@OP+T>U457SgA{jz?)l?WFB*B)g2I7iRq9Kr0aD*Zt z!4nQq1SC8F$0z^-VFd>%0upwGqZ9!~SL#17U=fng6`oTBBr^*hR0ITgQqgD#q!qli z2uNlY#hJcOpj3xn6#)UJGMYnyw1R&ViUiUMeoh1=EC7Ee0s>5BC<9>y|0k9RFr}i= z5J)RHKM`P7SP*|<2TERC0E$(U92Jd*U{3`@AOQhUsc19=!U~>H1O%8;j5Y+q z3N9o7VEql6A@0GZ3Lz8;2#Ctn$zA|3Oo@6Rt*9e31i}j5NCX6!%D}|JY6!zG-3_D_ zT#WclF#J?B5JM)xl!`_}Agth^L_mNk6%C8nub5KLfLm!$2T>mi#FexXNGtdhp+q39 z;1EPWKvXIk7RO#&p`u~&>9x2a1-!{Xjs3EWwix3bHm5N4VAf*s-mw*6M>KX9U^p&Fj+}k$>Vk$>PqcIRuIVu{B zp_Gzzq5#5;g9QRisc1BYa*A8~#!yaC&uGjC`#(5T5E7tTAnsmJQBG0OXbj~P6^+JF zPEpZl4CNFRjmAJuNgD~G`5|H+?5W`4K|n%M95MnBNGW(r5Rl*ruL%NTk~ZZjVJ)({ zj3m4$2uKDWUKj*m?tA?wPYG)g*6ka1#fvHQ9zG5PBz(%n5UrmbL|TStOY(-0Pzqh zHKY?6P6&hqs8YgeAa!3tzDZWpJSD6}9Jfk|dLX56vQI#ODfd*3ft1Q;hlqQysmfEr z;s7)u5x4Rh?A#Dxvw@U?O8@}@Q7K^?11Saf0|Ek?Qow4Iao>N+KE#Gknx#Z(jKvg& zKUYT;8NtcJGCa4jK;lXRlw#e10gxZE@<3V<#Ofii;{7*aq)s5S2qJj`sYMV86l}5( zOq_rab@?dZ2WdXQTiR9iq zeNR4-%>%-4g%A*Ls1Qi4yzCwdf!NBEz=*CBe1*;+o=gBB@`2RKlV%7w5|kkN!5%Bm z<1R$5U5Q(Mp0t!z7>h##<=1PXq$tL>mc?l#&mKaIk@Dkl7YUCIE$DAff~gwzh?RD&>eyqy9yxw2wQ9(+Q4gWXhvjJU}uS^pZireYfxd_!yl zK_&SKs#F!B_s8X_DMGtW(xi1Dqo^lBQB3m5BO;+p{!mSX+LII@&VkL3IwB-^l23#J z=|l|?f+)_HWP%^{LoB07Ht`jKWbIQu#M+P)Ai{wtqHYMTPx6UxAcUwHVtA8$;v4Lo zs22jkB%cU!-$ebZxupdxjqp+?f|$-qT3M6noTL>&rt^~4QD(YM(u!bn%ZkqC?pA^5 zG%|=bqF5TJO&ikb-rTvQO}#z(x+SfYZ0=gp*2lDoAGFcd*WV*WOaL`^FY9b; zYH4ro>*|`*KG4-E#c{vt#%MC6R;@`PD;Ab9)b;zGwxvsx&+A;}P0{47_<6l6+!R&F zPdNVF6jjO3M)y4w*e3a+KtR-jFH8zqgFXEn-EB?%D+inV+FIk{CYiJhQSa&QXi0L7 z=z>}M+9iD*!IwEV{pM)m5E}|R&_A%Yvn{E?20>~VXkHR#*aZbUR#EK*Ric(OFKKS=U^OPtmSFrOsa&+Axqn4lzW}sH7|iBA`$8EB5cqKQ z>!6!RThh_p+_zRf({3#3=o8j5nYN^3VBJvL3Mrsmw4_IQ&tw{tO)Z_x{r%avHzwXR zD>c|A=p<)pTX#Z4lX!7PQ`?$eFrZX9gRPqglmh=Vh=@J&z%5ZFxdnci_&LRWaZ5Cs z181U8ze^9V?b{@)tEaC&z$WQxQ+H2@rjC<*f{ae^TXSFBZxfr6OD1%u-x`e~5+*+- zBR#w(NhK%EJ0???^bB^lVu<2KOtvn;Sa$1tHQ@@@?dX-UtTqyg=t&T{!w*N2w&w(g$QZ3FEPWU$Yo2@|(1ogooS;I?$N z>Z&(n@|FNujZE4yEz6$CTBc>$GfB&|EPEzrTY9>dXpJUj1)wz=#ywqKf|lWn{w@nu&eEyCkC z^Yf@QSJq4ngmW2>1*#PDwHO>)HBdDHXIt@ z;(C7`O~o5l_$N|5uCqTD4+u8ue*E)j`iU%+?r?8&N4zQ^a#5-V<~4Qpv^016VStNj zxwghVD#E!yAXx%&`y}7p{flV3_cq{hb|QX5Ll(GOCQ&K)M41ZC$-_=OENi{H5?RZXqG=v33EG z-5&g9G$rN(xTz9Qy*+9(q3&B{Z6POQ;3hrd4y`epbvyZ=Id{k%Q91jc&ASWl2rI{( zApojtn3tXyQn^l!7-QTEeEyE85{!&j*HR-h(2*2E%(!1gCE!~N?OD^()7RZ5G8x|A z`dJ?)2^SgoKn4Ke$Nsn`+ikW;;cz9+n2g5q-zq{oV@A@}=7DCZwO)0D*5=icRH@b4 z*4c)sPKFK|(T-Ri#Z8c>GorO^RdcssYf`$k12we_^d;I7BI-y#T07d?TKk$in_3P{ z>4F)P(n)?wF+jNEqR&I+AOq2T@}1F4jv!tzKj+SH9ftZ34IWlYr(IhsT^t(%B>w;ZQcDHJ>Bsj znpAG>=EI4OPTXR?I5=kqQBE5_%f`#g=X=`ckVLykcZe~nc zV`Y|x1Dg?Dk!(uoJbkvsin;;bdK0ocxgv>cZU{G9G7;ik>biuNX27k8)1N& znp>ND2a*h(G@8-scDp;;MvzcWGVnl8-^#&c0BoBqnFH}QBV)T|0k2AnEd-&LUiv(& zBYkb1fzpEb*l~eeGrn%`=pT?FkrAiG=A9tg5vQIK&E(#jC8* zoL+3^l94clLbCdrm&Fa+o?YMrO?_?sZNWG3xI=niDTCm4j6Hp@p{;ct=-^V|K{23O3$>je2+RMbdBB36{03>WG&q3koT<`MglH!s9dM zH12IuEMoB^<>Rhes9y<=$?%Ih)el`0i({~BfyiEXUo;8hZ=oi&mL4pl1A{RKSoBHD zTb0n$^bmHotG_?#s(HK;-rcq&#>dnV0koWI8({L{u%E;mOM`gS6mo8jVVbBkAH!|@5w3Bt$-XBdqiQlWv=nHmsbS0Ak z;jt5Ruo`stq=(5g9RF<*wg@EofX8<31JP8)```zn3jWHu6%RyZ941p?SW8b|2ZpI> zX-mS$rq3`J@~)UsOrw$9p0-2_vCxh(0=+$hv5E}G(zr*xn8fbu2cq#u6NzM+_V#rI zJZ=_twy?5oWfN4zWc1B2;q$PL#Y;W<*Zd$Jtwhy%clv|T6d0|trqi%I+8*e`207*# z(`O{FV_9Mv!sk!o^TYUgGF1KT5JJhfNvHaQnQQtCtL$f|;>8Sg&Ur`&B<~J-D4I5n zwI@@nzb~2ob?$T&U_a{I)$y;p9>VJz0(<452rn)$_lt)ZLW#dBeiO}vJGR9#ltCB> z@G^q{@fsLNrX(I6`Aswxet#N7QK!$Uj{cUO!B|6r?`S-Jt6`RkNl@?Z#m8*E-o5mj zsGN*t+kdvhvY`30K#|Itei3Jfy*A4L@_GgbuxW-ohd-${-P0o}Tfbl&S_E)oP5Oz~7rDA#6pfqiI zM?2Id&DG(D(FB-uHB+O)aj;?=18K5_8>w_522wS$cy%=t^`bi=;U5}>5mYQ z)ev__)Fjz%?jzA??62T0>2`l4;se?lcibaUC4OYxDUU?u_>ps0B5TNkza?L%43`!W zF3BD2g2vd{+3e@OMT)EG=x*s8Y>ih%4Lk>&x(E7{<1AX7K{#X*+l?nDT8M)I7fIn; zg~(u-h*gLThDq0sUT&N;RvhZ+?`rPgB)6z<0APjhY@>}7K9W-Fa%?YP7UyokLa@~= zcRzbHnlJ4MYMyq4=P zUgy>PwoaVy5MW04E>Hq1wm@`!?1G(K$#2{Fu8!_v+UtIPsD@c-!rNXR8Bod+o!_F1 z;e-Bmv9RZCBacCql@-2|iXhWmg)Hb;jTGP-WUnyhJTU9J0Aw1Nb)5kD z#KbGp`hhMrOlx_gHqtU_Onx$7)-T(#Gu^P$H-MDw*$I%f%l7O{%gSZ46Q^oD%W#;$ zewg^gnM$8*!SPnPc3s3TJR;r4Pec=s)%amY)O0tmXzrFVv{P#Z;7lD3c&tv@A<*zG z{#8wPTgS5Y;-PD3bWKl26L+zYSSSRE5vz3YgA`o4+t$SU2!zUV*F71P9AKfcYM}9g zi{r^{LKAazMPO^m*~VK8y3MW0T7Vt*mro*yvW2Ls(E_V`6J<*tc>aAfX;(Ny3N}(? z$zV&o==+bbBbd^tG-)1qVv_xx1Z%=Z_nKQ{L6}R@rIx1dZOM1}SpX`D) z%GD8C7mQ7w%oZ@p;K>OwJR;kZn%X*o4|Ii*mX|dTCW{4JB$F?eHLu0VXL5*VL8r8x zWqr-@IKyqyO?x_;ipVbwuHosZ3b)6D;YlA3TTCderE_`Q2|GL&oI01|Nq0LYw}?@` zd}=r~_>@tkb9qzC;1aR9ZY>Awc}V03pN^(&3Fk@o#?#Sc{HSxE1G1|HV6sXFaRL|~ zcENKpp+Z+kX;|M6dnTIFZc&=_`_vJrg>BND&{Uc?xhoxn&JkP0HDr`^BHVPrlhQqf z))2ZY@7{YRnl@xHk+kyuo~7|b%-h~oD#ylEPMKO@tR8HkK_RB4N#(d$M{8Si=d$Kl zSisFP={f5O1}IzTNax{%s6VkmSO_M=4WAA)cMPnC1t{LFT5P8OM+vM%T=8Nw;Xd$e zG-Ybu_QQ(q>L7a|viZ=^@@Jzm{(si9QDwPBM$-CM_jM$vmptZvHk!(kuRI$?LmG04 zB=1{6!<6}aZ znC@MxIGC-ycWAAMyu3+dWK-f<1fd!vDe&?phLNPa%bOHNlH$%{3b8OnjYcFwch`3H zP-nDALP!s^_uyc?r&GvmLim`z=HA{miYXzdNn!=UccE!nPb-gZq#j+VVDp1|A^=^W zFi%>Wc$^dW6~VW@`+w2YWAY}LIg{iAoy&bVkP+Ls#qgEBs1eaLQ^w*Xdhq7)QN=6A*#1~p5h0GZbeV2~zo>nU4KITt9 z=*bD-1OD`Pz@tn!1o3{{$InM4JJp%wMHURm%U}uTysEPkZun;{YnODr+vNppGJSX- z>6y%KAKphH98w?N#~@nD#H@!&IXmX|FfIl@%8!R}Meu=s02}IqEk)J^AMD2$t!nP;pj)DVR1kSk+&E?Ew%``X zC+SOF-KJOI`RJnst?HnH;6nwi>e4dGSNC-CxEb%w$$Vi_(>fhRNfP5d*gEc#?PS+<^{ncU zzS~ZAZJR7XwvS!6go56O30g;YI7y4CU`EZl_8yrAwu4>Q(FMzmjih>EyK!Ty%Z9@j z&cXp6IJSChkX${sdfb+{WGeyA-4DlBkKYneQzTUiKYWrN5~Jb4biE z$7+}}jy1qrhUMG|l7fOQsq^AgMQNG4Q&aZcpCyGbl~S^FJZnMlTWd{DhJ)5}F@|F4 zjdN=Ga*NdPU8w;xM^aB}O6zl9Xv#{~Oki7xEh#0B(Uj$VOHvm89le%KYTTN<4J=>1 zDdnKQNNT$h)<`n~X)sSy*3ackHDE)3tIe1Pa~|U)Ns;dPyudKS|JL`9y6(ek337kyCwrg7{WF6E#;+=Rpp{TQ>CIb7_5oSYG1 zk22PWuh91@bZv zt%xp`Mjj?oVMUKypr|c znG26edcn^7h5ckHhZjcVs|zKCH+}6Z*)RrJ!s%7Yy)Wf#g19Nu(H3-V&D(D}aTdjz ztK0xH!4z?o6n#mRQcn3s5o;hCDK9AKm$$MV*fe6g>30VtNg}q&lE!pDw4@(1 z4V4$vn$_kv?I@M{HExb2t(FsZ#Gp{a`ukCs3g>Cc#_vw1a6M14`Llg!ohq%7YK^%{ zaT_otrs2&PBPN@@05M}hev_VR^`0G{)XI&t?h8vACN(=r(|F%ac=8xcdN%u(B{dg~ z$Tlx-9s_3Gds7P<%en1lNv*J2NUifU=|%B!OWM#}Zb>Wrup|*%O27SQl9Z{8aCxaE zg$0#mHEdpt9NaRkfzx*;Hj?Dn-@LO7h4uJl%e2n(WZ8O6LZV1VS}m!CK@T~T z44U*S$pc!@uk(MmWc;0&K!fkRoIGe3X+Cert6_KoFj;MhP}&@hS$5A^fG(WTq*38?tL@~b&*6v^J4l8nm0yZ zPD*>I#g)0I936>H0QY-heX;!T?%_PTbah#L|=PaMxG!_cbFKeLyWf0}Xw;?;b z1TREp(P18!VWkM6qRBlp>6xI@lEyJtW@J#T?4z3L`QTrcw6Zg^QnBqv(0{Rj1{io% zV7(Qz?{2lE;rFU0z4#fOlUhBOG+NTWU8+ehW-iSMx|&H0(hR^S7;Myv_I8bau2<%z zIb%aqA!g5@6JEbqX9W%G8#HNb;hwjop*g%xYE4+9XtRfy3_2PoTS5Eo!aDW`J1Lo< z_edsU9%%A?P5ObHQqMLJ1VD55v!oRsuw+b{qHP|odUBm}_oTv~8; zgS2PcRCk;v{TQFqAedXX?npAp$Ztz#yt->-y`TwO-Ai#Vo3@go9M;g;$m&r}X2O+? zf{N#YMzaNl?H6tCnDgxBX~e8(bBBnx?!zy!KfHS$C3z*1o_O7St|VAj<(Z_2W4*av&Ix!2}-LrX@el!P$i_ zOUy|zK2J4t9XfO`;^7OrQ<#L8zpYX?BuNtC`8X-FZus6-SVuujok8QamZEX7dKTsA zSj!n54KzmB)Qs%m_CC>@STm77(i1w+LiR4 z5Rs>KUBlb8zF`@)v({f(6iUcy0T2YWPygAP2{=aPfmsyO%B$>6Ua#kseyz$&3}0n=@KiE_wD zX$8{StSOR_TG-J?TLn%yMA5KeJ1CE>6e9?!_YK(VY$aJiAe0Wqhso%B$r8IT`x%p1Ep@OC1Zk#BW%)0 z)9NGBOq`KLQdC(ap7~gP7u79vRj(M-VM^Pm|Yc(rfC^Su#dT zd~JfpO{Ac4ak~j~v_|HnI3Jgntm%zMO4EKfb(bbRn(tcD`Y`DzDeTwaeVBx+evFtL zCI-#hh@<(mbyZ%ZW6znxgXrKJZ$u5I3hqi=bi!EuRewHRZ0e@l1n2+RG zF=>Rac=_g2T8=#GXgNi@(^_ve?L0;>@pAl1OWN2ys!6}i`IjXP&zawlZ(}*Ap$P-T z%=`+vh=Wd$W5x*Pq!k^6L{*x+s+D^S$>_z>mfw#yE*6fnvP(77+o&$JWK1yen+;lz zccvP%FwBWpxAdMh%LnOXtPVMrh{VST>nvGtUyYoM9Y&nIYZt8XFC5FYg8r1_2e`L5 zPQFF*_GX;+FkWHEE%dTHZExxt8nrONi#g9eI!SWUtj`=dA-V^3Pe4=R8)6#>JWt|Y zKMorRJYZnxPdQ#t@Z-JT@uZ_Sf(~fPPcsc+7-IonC(mda%rMOHbknegVU9IC`vkV+ zjbq2105od3fJBF2={g6=3AOgZfFYj+@;9DPU0w{&Lu8viiJfq>wa3^_&H;CdKJk@brskr=bN>Xc#PyKXp9Fc$hnVJarMIjNkE{rzykmPDy!1_|Gk*4IW<54@+D5Ayx!k^fk(2&~z*)G~QyE6C+i$ z9mX4-TKAJuw-*~#ghl_o^F(VSjz(AYmdYf{Zw=9 z@!k>*zZf(DiN~3ZjI>o7b_Ac1n!B|K^RINed6^)EB-eQN$}&L%gGuX<+q#`N!n}Lc zN+4CQsX961cCGC^Ah!oF{CuE@2p6^V-nbUlIrre1lgZ-gy)klfZd@(Nm);yB19rsM zFtN%zhzqogp~=(B+(DWu=u}-JDG*w0Q`bw%t5MH&pobZRR`G0>-WVe%o)twKo!Yv%)dsD{3W&yd40CL{ZQCVn`NP=V zx_~D9zE#ujUc2#mzKLPdpODH zt02jpdo>BM!`$O6iF%nlSCe2TN#1Em_~tP8FP5}#C#{sKAonGA-<9yKTh!7Wf>{O4jEcIzDVumk)iD%BQ2n4M3ok6`vd{VI7v2H($Kq5k`36INbbFw3r>*a zUoB}}o7Ru2;K*n6J)j>H#s0cL*RKkfj$#Ryo^`Dem(haDJOsILB{RV%8CBvQ zTf;R00#S;7u|{-Ty^vy4x(@d+rh$j3AlsVsjkU6_AlbYZ+B&b}_N%qv zH6$C{_;0}v<(;);Oq%E@iP(#x9WJxzVkcRt3&qNZ%vH%iJ@1b4Tlj8^Y!%4(T;&I;F1(hy; zs3}9J@^s0wjvOi}C>~PsR884;H%SV5gXF!eDMNkK5Nm;cCV7pTvKE#}3fh_EZPJvL z{GFy6T(qIO(*0|wdOPTv1xbxhF90+ave5YSWTUDg;Ph0Zo+9A%M5B@-;FRVEt-4OY zZrlbU0Ny~M*;^uJnS#3o43_4%?ixvfEs&~kPi&|jyCuzilKMhZQbC2==?vz9EhKNT zrmW=Ik^&=0-W{5Jga)!;czAQ^%v1vd8EP} zayGh*O{-h^F7)p;XJeVo`dV*f9v#kw94~3gNWAqqXc2)TEwjOrmb>&Ej1A6nHPde+g6T3TCwE?T4Ow4{D|E)ao4mc;9t z2mafWDYTkLM0PkVBH-3oo^7iwn0Ai;9eGpW?;yh3tfjYG0V=Rey6`J}?QaYV0 z+>YmyK6t5Gc1G^V^H~iDD}(o~^KJ034HSk+pMqxau9MU`p?Kqm3aBxI`_gBiSkN+V z)=?00du+6ZKKumZ*~Jt+w9DJ6zDf$~qF4!^@TutWDnX)1MA7ZJcMP=koi3o9#_Ow2 zc8`mh6b(+cWoKW2CTc;hL&~R=xjQ72j7T-Xy~89Xjge^5g(R3~y?rHR3(|xl?;tu; zb2ugx?duRBz~DvW@A)Ww*a!Y7)i-N&Z!n zeqoq)u~Y?JNOBL-q%O@BZmlM1RphdJgC&gzU(h5}Zpj^SiB#n~RkV4_L&UP!grcom z-cOG7@h04+wb2Rb!%cCg)_T&4FD@u58dcvGZuQFQVc!OS(o0$d;c1#OA$hZ;ygK@d zrYvvtclezbpao4?Uc02cvgf`-B^P(Mw26l$6BLvNKh>0dIP+3gYHCnPw#X9*m#gF> zWTfRS?p67W^paZ#{$n%vA}w?A0=l+8_A)_^dq9+Pdt62Yz>kvZ(oAk(n0d7%>4GfD zCoY3Kiznk3{E$95lC{$&){2LvHMw{bGd&&8)=aOL++j&0!8?}JPfPH2a!Sj@^UYEx zGE)0ts0E4^GSUN&mzez*X}N&sl@+~b9MLoN)qU**cRyTnF4v@W`b157-E`yS{1i)= zbo*{iS+C!hlqdAmD_GLg`G6~=R!`{FmNXh%e+4KTtE2KEraYS{!NEeB9$o>(kz6W+ zzPXf*UGTIo|rXmK9j^dY49+u9dJ9kKC1<7wvM4%)s*GY_7o^ciX9 z;bl0X$;+?!p25hZb)=6gGxV~RqGfOSqJGzqO`lSV8?6*w{H_(H`>fTP9xXc3O3`!w z?u+`7x#AOrh@y7vF_Wh4jktHIe!-f+^by_?#L&T^DM&--B?<~|WvMKC@r&y1WMpy8 zfES?3E}Jq#0Em>|;7$hssvmTxaA=_d*U_>89xdACH9}XFK0GmEhA<2sbI*tpwhwDb zci3XZ8Oj-+R;EyvBd7#ryeTUND#0f`+I7(J;Z&%ors#sLwr-nC(R_NqnL`5%b5hGi zEiXV(wO~tWK`mJuCQR0>6j3r%V$BqjO^a*zZ)DuzU9cDyA|)<@Bdgb;G?5|;%-uNf zgx{cKrPy8U_6PrMB2iACp^D+YwgcMGezku1uT5ImQ>RRSQRn#{Ua?fJNl>+pGsg{e~!}k|=nlhn(Y4@pl+=CU?!) zmh(Z(|L`7SVT}wJGy%@}5QR&TlUk$Y0ASlr`>3eDSaWGE;zvaT4&iCm84Vp6w1jCY z6HP-1#u?b8>+MCsF3s_H!c!L*jVKs@BaC$&c3CAFOEAtrNNSt4?_H#`HiNe{t&Sqa z1pX{OBh_FcsWUuXV>_v7j=<bfPOwIg+~SqQI(=9yrUIUqxlQldBG>43(p-@p0Izo% z7Zu%$g)@uKNcSAiY)Xb(@tLtG#Q}G2>~Q*ik;oin^t9buGPqSO(Kv{4r{E2VXgZpa z8uARhShU?6#>`ZKMvDlKd)RKVB8Cl*N)(NZ7}pPGGmYV;304iBRguj%P)YZcE0OP4 z(S;r}jIoiCTDfU@8Dz2sR*bW1?IAUj$+8@!YD(*P zVgrAAZOOE~P*Hk4NT0P*il*yH%@Q1A7=3=dQ0W7RXU()l9vPlRic~&4q-Yc^KJA8f zP_c@mp7#8P&XjS7Xhv#YNXFlmLEJpNY^EtgKBHxBuIfz` z{zC|Z(tK)h zz*o4+h9hgqDxw0i7Of%O()NEL&w9;B&6X^!m^7cTvb1KH&0aEO!QN&E+rVD z5z6T>7p@{*kh+`7MTsXF^DiEyz&b&Pn59=J=`+0LBr0jm_l&jhe5yh|iy>aoe(^`X zjNh}~aD5E%e3w@4GQ9943O$TFp}0VXXW_Jy95TEREjnYsTcV0t*&V*sSl$*LF2o14 zi|_YE&CpPy;U*KB@LG{jpz%>(G+vm~nw;G2(Y~bhIJrk+8AYA6HK{~nQUvlz(}0yhQEzHlzNar5lQ*r2;q1isC9Q`c!w+HF9RL}=lWBJV zyay3~ky?JSmKn`&SY+tX|64m*q0QXNHqzJBu;j*7rNG?k?XmKS_4#_YgCgm1qRZWRz%=*De)lU0JV$=Zmzi ztT)nVh|8d=czDwnz0uVMH*XUpkH))J~hJLSjQ%U)Bw+?A$jEeaWN9jRqk0_D&TlnAAb zWysR=GRaD@v}DcwScJWX(u}c{2s+}dR`Zb35fHdOz-S@$q}Uo+1$V!Ll-=(!Ul?rr z>{+Bj+ExbP4y%Z`H6idyC>|w;j@PU|tw4zsH)SC&F|cDikp-7N-Gk-RnpA9MkqT2C z2Oa%XNGnZpPe3VOtTF-b-5xXSQoW}k%hmo+b^v(^JQibzsfegk@b7Xz{zM6rsRJvU zZwW$nh6F&{w(ysIZj%lH^=)pYJq|Hp{pyvrp$QRdU#%*;tYHV`e(YIwZnuxv!2}O* zx@4;C3^kZ%jII##!E-rkY1^3GZcwtMO=DR^z1Qk5pQP18NrPs59;W2R$qEs};c0-B z&_2S2#Z#lm3Pz`QMLVr6NjN8FxMMRO z$)sp%Wflvc)=_N#@`~itMyrF?1uL4`{9sf(f<;CztTO(KR3~wm?isY$@?}RdCHeHJ zSZ%#YZMW+|ahJ4m_xYg;!Dz+Jr8Y+1$Kr-l+uWd%E)EO)u#j;Ai|G6}z} zoa?VkZV7Lv8{BCu;+@eKv=I+rfDW7iI96GZG3ck<6= zNi2@M#t&Off!vdNqB^kBE zJFB8_ZIZ>giEoPfjPZYc2wi(*gYO#bcjo9(6tNAp6ue!wF0F3W)Y*#dnxVtXUCb1)|bIso-cIlHp5s()n!?jWv)y6c0zrF!|4CV*H;Hr)ja(R(jZ79A|)Ln9Rkt< zf^?~b(%m5nmz0!NP^6V^3F#0}L0Y;5l?Ejh5c!>ZFK6HH^ZefL%U{dP&Y3;ub9c_3 z+1VK=eg!qCf4qVq6AS&QbfG20YVqmAL>}%!*&=i@R4_`&7Ky_908nn!f4+cVHyk=w zDv%L?N;1F~`^S%209otcRLei?7Yee|1(NW;jyxg*%8+3ufJ4;Qx9C(C1SIit*1S81!=#Og4KA<-zzp$3{$x+{HaD=Ky>8 zkg6d&n|$((jS{)sMfpj2o+EYqbM*x|Ed`VBpc((bAC>Ph63zJM$_p7^3fq-`t-YWV zb;-zh9^~))pQ|ruha1N8pW&*gU$Z|uYBv6J=>_?+#o>h^IsxqeK#H7Ww;iDepnn9L z2w0Xc-zWG<){kU*b-MA3i_ z}VZ~s+ivirB?PtIR!veUAf%%TkrGOeBx=;yH z+v#+N?4KCG9i80()e+z>25=VxxTBK|p!xya#Za3tXc`z6z#ZDSgog^II~4Z;+duSK ze3UTiyBXC2xQhYY(P!h)T%ZKt4sC|PN&xQAcNw4o33O2==qZR_MZhBB0C#BP<5WZ( z;Eq0?jZ`cSaEJC%;C=viae%uxnD0ax*p=HIGFFyD-iAoa7UjXMkxlk ziv!%DeGgay;0}G<0UEdwfIIq>E$VtG*irTmI;94S0NkNGwSWecfcXxkri8fwcX2S^ zp_Fwn7vPRQ3yM+B-&2uUNJ%1Q?m6F}fMG$fqwOC=1ml8n zM=p$DbujMG`x7XEaYw$)K|de?^Y0SSOR^ceti z;rR{~H2@Oubcbk=4%GS&`mg{Z0C(u@I(!*`JG7F9X#jWVBoUwi34l9vmJ;Ry-1*_@ z4&4U=hydK7b40KRz#WPm1~ec6aOa2TI}|YkZUo>CZ7spF0C#9t2~C5ZKfoP|r-C~I z+@Wm(Km)@9xI=_AOUbk zhZm!66W}fYraQF$03rZ)Xh#aZAiy2ki~=+u0dPkLx}uZ-+ywyc0s!~Z0?x>1j)om+ z|Deqp_|gD(0f75y0cB)AfIB)S5~U8{j*e$U)8GeuTACP=JuN_tYQZ-m2*G}8|4yp} zBiR6VbU+^Rf~R$UQ7!o1(P42YF2Mb?+%B>oz+DjFE(py0X$f3pKLo)2v~Deu2yhn! zxSv*=MREb|r$u8?G%zfHyC9hFP~_F=^F6K4ij+8o9h!fq6<3i&fIH;+fJFfA&`BLY z0}mL?cc`E#%muigRwzYY8J_R_P?=G<9};%7{SySZLyj`Q21)?#kXH)k0^Colaw3%g zI}aW6IqipzNI=4LTJaLqf^`U8MZikX;Q*+PV7^0%jNr?F`F>h05_uVbJ5<~e?gwxe z0=NqS+)s-pB4uIN5l|B-0l1@gf>DD3^Zm3^AyOF3cOhWsPpb>qlE5v2~`4sA`q_XKc9@7kgI0o+dulEy`)Q3fh>NaKgY0)&b`8~nB~GiUK{N!qLJX=S z!2Pu58Bzq`ep<0C!=4JMh;*D-n2N34{3#+;tEaRs!60P@n@W z0o-*E4Srg{T?aX<(G~)-f52Y{wcv3<5zD6!4hm3)TL5?9u7e6d00}VPp$$e@0xau* zyAF8>3veMFX!{54b-_e1-+{jls?PvKz3^XhO%)E#Q z0z58&y9k)?P;N0;1mF(bbyX>#fP4CU5y+SYm!39zfCS(U+;z~o5co!byAGnk62M&ttxw@M1KM4OvVTzeq0=Ei2fRQF9v1M|A>+$o zF2G$B;11k%P>>Z+0_Hn()&rIWW*&0a!S)ZGml`>pfWHoE0TF;ZaMwYrYM=z*E(+#5 zaMvNvfWe9Z?!aBgj{yEUeo=rs@Yg}{L_i66zXNw2#05_a;0{$CgVlj$-DyBB^5(#F zKXun3?H?3Q42uBVp-^Bz14;nyz+HztCwAHoohldk1cAE_YQgso+;zzGF0cdy`>Fi{ z{yK;aM8JFp{yKg!fV&vL9i7`1r5NBY25<-NI^<~)STUIHVhAwbfxiwq`2pWMbT|YS z0rMTW>!1KUa3=tF;I4zX;6?!M(76TpdZ*JJ`TYfOhqi)XHo#pB;EwXwp7&cFxV z2m%?50e1wriv!$&zm6XYT!#Ar+@bmlfCiKR+@bhom!46)a3cVBboMipI)FQH*FkBY;QbG%36ucb#bMl$5zy!%K&?|H zQ0r6z83qlwryxQf{6GT69ijmV*vv!4XW{vdjE#mb1LF?SfC!8`a?2j>2jdQT6~M4y z+#wnm7K}SGu{$h_h8?nh5D_SWaffI?35+{3VgnY2affI?35+}PNE6%-#vP&o9q@EV z24SDtKgaIn=B#vPgd2_6EBJLFmcI$$#|0DXS}B{1$# zM_38)*CErcpI#8S>mVAe1akJlT!1_DJqT#94(MG2XlMxpM$4J4t?wb8jt|E19u&iZvYw=%Kkx3AOdiQzCGZ}0NkOaJ)i*zfIGB)g}DHC zXaNXlKms=NkQWQy|A3m{P5|!E3mz5*xC3_`6aWq+0PetD2XVo@1KfeT4vG;!9Toy= z0wn-<;I9(^{yL}y-wANnK{Qwi6c>IvRN$@?fI`9n4b}mvgJ~$(k@gRH#s(092*4dm zbpmq%?!aA#48{Unpajf!;I2dF1Bd&8=`J7y?|(pSpakF!Wdnjm0PetDhm3N9xd3-4 zzYm~+VS)KB0B{HHIspU}Z4HY6+=0Iia#{i!)9Wpu?mId=2xa*+D1|R|R9eq9- z^~}+*BkdoQ#OL%fz+VT&_`<_NAMHhoApLcy?OJ36Fx&#T19u%1^a~FQiVFt)fCQNC zNOv82{fCU(g*yV=fxiv{8@>}Ly${?E;11k%P(Ppq%y;0fL&lE6vS7LkLgnpYBETK^ z>yUAGfD7&f;11k%$Ver)ADHjJT?cW24q)bCcO7K^&}YO@4;ajM;ID&1$H2XV`3~H5 z$hbCGF_`aAOc_iAxI?MR0S!nXVMp6P;ID&Xzu-Fo{yK;TiwFVSfx8ZxVL$@lewuO| z`pp1$9h4OW9u{!dK{Qr)T)J=nWeU*h4}`?S!5VH(-bq^|1Kwnl=Fn*xR60%+S1aN zP8Lw~6|@~HEGm{v>cq>MjLUSD9MOCGj(e&Sjo+`bFC{B#)%U#X_Io3~M(6EyJbAiU z5ls55HeTj?g3$4v)WcwGPIB*DvPuRX43p+}-q+@g{?=!v$C|Eoe)<}p?96Av%V%Pe zN59kbJ?BPFN=O!UXJGB!2hv-9bbY2gZ^G2)^zt$z+2Z~L zaYTNVRXiIR-o2smxu|-6{p|o29swGK1H)sUGOMIlGDUH{wuig3w5oJ*G@Io%9Pw=I zA)z>3>Jy_Qg*_$g?QtnO!+VQ==@A@bSo2u1LHIs01;J}ybw;^b6j-7kIv0F+jW^Q~ z@_ea-?fx8nI_2xf%SsHaYWH2Y#J%!D4n*?kql!0H<>tRJZS^y!$$b~39+=AJS#`J^ z+vAZvYEQnC^Q|#k^K674%Z-ei-bOQ#k90VAUMe(qCOqZ-UKOG+O@ZTlr-a}MVv-@D z?6`iI*gSkrS>J}@d@Jl*c&K^!(0M)Pm@K8Wd3ec~qsiifntH!#O85ufWLK?(4}<<98PM z-Z4D`Igy@e)p{lBn!IL{x6n?C$2yEa8-jEglooUd(Mp7#s7v z+WW+=Vj;MrN&DlxO_Z_mcg5jwH{KI=r9r%*2ZS%W6gV$c)E*hfM>$;n%c=WL0V7JC zd{^nwnM+nyM@O2&GObiccsU_Gd4Gr^_4U8EcT(oE)L7QEwBcW;$-64zM!*{RxZY=W zgFrYpYlI}JzCc2rDDGMy>m+wz&1D3=#FYB{u+R%v3DwumR30Qb3piK0dj9Ab`Atw1 zRliizQ&*O2e~T~qL$mU`Tx@xL5KBm9Vqf{^u`l<9k9RRX<_gYEWjm_#wpt93sQ%)` zEAErLa&5t=5gkwR^@hHTxu>eE$6q+QGQ3SYC;h^LR^D*1scrJNm-wNJ*-hekLG#S=c?LhbOT^{e@zto8*p~xo<{Ivul|Nj^fWG zXIsLQU&MUh=OLO)PwOSISOpo`egf}$zTgtzgrQVQFL5%jk z9_Mt9wtH``SG1Ptw;y?LOy;+q9vcf?WX)D6<6aD7u!kc^vPsf0OP1X!&$?pE! znxp&}-$~mKv?Tb()&pd%-1kVNEpgfWpGswA2i@Sep0hn!!5ee)Y7JWs&F0_R6s51@ z*dQV_ReDy)oZERTwk8wnWBl|_o+Jd$rPqNyUgc-`vGIBbV?3`sExHyi!)1ue^v6h4 zdRy`CFZuJIUGcU#OE12cKbz_*`7PXyo{h-CP-gvE(a$6of9=VplTSpS3f#JX9sOmQ zNRXxxO-U7^PL_W*^W-Oe68#d@vScug{)IH++g%?${hcKI0w%w+eKpBx33U2xRE&`5 z{pfP=W&G|hHDmX3PQf2O&ZO#}BkZ?o35EkcIBFT6r0y5>3gsEC-{@$(@pkdbvXavz z)4nE--q07d3?bz_dL2oQ4?E1|-b*j4&AcZqpL##fKhdHS@T$U`$}3NlqkjTbU__|+cm2($EG)>6;n4!F-#Auw7CbQ2N zB3S79Gw|MO;_aiG!TiR*+==!oX7cR{pS^I+)C~4fEQ4=&I3rob&@$wVZXDCMe z-k+(~Kwyk%b7D4TkOccZJ~yc8M9$Sj->x{Mp>+85}Qb9 zcE9njw}n+{{Hd4_F$^Fo+DAla+4(p#L zikUaW$9TK{^t`T=jt=LooE`UByR>Bc(%^4Swg0Q1wnx`zXG}gW(S0=*rNHi`F~-B+ zT6vihS>xw}(D2j#@q=~oSc=Wm^__hHr|ayT4(E_ht�pNnL~W=*%Zw%kn;!iprmz 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�qsx(>J#P< z`|B01^q-0Ua5Fsr0b{W9{Oe3XvcJ%L5FkosWlJgw040hOFR8t{fwTJ*_t}=y;9vP9 zf=CUy;m=RUj>(B4N4sef@#4wJt9vJ-jGZLWRuKS-7TSY3zNE1!R+8z5B}$Q^x-HxZ z=+}&V{s3ME=JTu1s8#(vZC*z`R%(JTCW7A2uQw+L*J~-#6lrtCM<2c9>LOL9oMh`< zSV3JESm<=hgw_-=-G6DoO;7qM0_67&@(fD^T8!zLtUph5e}%hl{u+^r&{S9@U6Fr9 zUp_Q{{UdESO|U{U^9z;zn0U+1Qd1t8d7d_{vleo9!dG~8Rk|-VpZpdY=b^j94aF2R zndL|)J;>_ZwLS-8Xy`x)ZwzB>C2OlJ@zE$|15mYR4vPpPp>-viAkBCOS0iqoFQ~O= z78Z=*!droQ8^rr=dG9~7%JGhmh!Wv6Xydbf|FJHgF}du)(m+jN-nTaxuEjs+#AR?O z=5aFBYs#~&^ih$n-4c^PzeF#IoYq#*@vv>yeY{M0!_Z*`i1pQP^nNVqM=iM^E0k8z zcYtAf-L_!g7?{#n`wG+GNMpe?ejuixE~FdLCFCAv9eB-A8h3>z%zjIY_tmQq^ye>a zITN4nZf)Q7LeAY*|ET1UPL(=A(Uu)9A`gdxVaKZb_XTgAM|c~aM0oxE?}Y3chURvz1-6ViJo}H8Cwh?T)?f&hB36Zhn=GlH+jHJ zla8j`Szl(5ZmXO_jn~e{}H=Ky$G8JwRM}_ci0T3?2a*XiXN=p zNrH&y^^&AXH0M{d#>7IaGCs8$0{~!n){#8OK0yx~)(eQ+tZx5|gR`gHI#I$m*VPuV9hKva^@ zz#i$JuD2!GGx-tT5~AB47A6Nr|K8Kw&IMA|OrSWhVh}cbs)SA3WKOT16}Od)R+%7~ z>xUP)>hm(}mt-A;a`SKf`Pl%R_4zGm`5s0`rfb~9N!38=<2x!W?vtf2mX%(Xry09% zY2FZ_${hDhuc&^P*O#8#7JD^W&(?275LX{eH)u_o;M$j82c=lDqxlmmPM>2!$w(w; zJ_=vhn^o~lo!r7gY?!gmd0UWtB-tMpE^T9(#ocjoja;C?zxb*@nN0)eHb`?>g7ds{ z#WimDxX2QM_D&jKkR{yf=S=?3dNa@0iVZ{`SRPMObV4_9t?n#N<@WkB`pedzwnP)E zAx!!4F^<|nTHQZL?zue!5m)%m49Q$JJ~@(N@Gd9i^c-7ZA;N1ymn(}n+XsV@Cqx{$ z8I)pCv!(U)Nhr;0ejhmp5QgJjk3Sr6n|un$0B3FGWW4)17RH&<(X!*rfmQg9-?5B8 zCR+X@+>y*k$_^5>12tt!buV)9N6%+{cwd(6Ux4KEn-#Iznw6b*KKDNy18N65O1{2^ zad!~z;q1Q~9=}f$O37dgS*XjKka>e>KU%){AIu&C=o|11pB@&1=MM^!2gIdjPZa^r z&ifm(2h3&zr3jYuIEk8e?WriCQTpGXtsE|iSiXVFppVu4r5!LKc>bUmdH%^dfbP$HE`X79Rm=m z^~({|?CT}7a~u0ZG2&w6Y5v1SO0Z0R>e| zEW!)f4&S@8ZyiKqR*?XXmXw)8zP(4QG{wW`OXN()LQAjliw!yYo$mCgsFRa|(7KVC zw_jdOy!_34c}rigshFEnjHYr)4Oju+rpZaxk|_`F7fdni8A7k}kwWzn9L+&3^bl8% zgPly&N~L3V^r{=l9wH((YgR@?8!6Yg#2S!Q$S2jS;Z%jquEpfnZ+$M3wkXsCM(?-i z@lVGA9fYRawXA(t1#9DUiWWsngiBwzm7pIAU>^m2cxjvTc371Q+y`sx&5!|e9ugfR zwo2Wu*zj#&OMX^yVafWBJEv=FPpGEdx8H-|@gbroYX|R_zowVb24iWItC3KpzPiF}?fSve8%zPdIX@^{58VRw8DIZ24on{ai$nEI%??~?uO3^G z=Fo()jy^AR_LR4lll7i>_aPjxfVT#dXvBs?RLxFUu*Z9flle1orErGY#hkxAG44wf zU4nT$A}e*tl?uu>wEwY2M{e|DE%|c)wqMy-+_2+L_iiYx#*9pMF&Db55DBhYV9Ww} zwxyqi_oxVVlJ?6y)Wu+pfu6x3zXW~nv@Ufh0$zxXA0sX&r%IJhy{riUa@Du*Enmy) z0=`|9pqUE&V7;Ui<=RM;WL!eZ(Q*CLDi^H9aeJ5iP9ah^WSz+DfZkzN6nRO-FGcA? zWiR6#!n8^Lt{`ej)%T3@!R4uu%1xe>h@s}s@QbDS z_AEsXpzYgOa0Ilrj(3{^aIN0Ra;ASRn*~Rz9iQl7O+xb@c^=xSPj|{|P0vDn7Wz_p zjUwAA(yp}o64xpdO_4K|bu(*3m@_(gus@_$Exj=8nX9@Xr9x}QaG6y69rjaD!Dw_7 zMe%`K>w;Z3EtB{Oh|Wp+0rECZ^CUm|(*PrlL=89ntlWsfP);Ns;Kfv6`T&dK6SDhk zqsksPu`7*Mf_dCB@_n{Vm=3+0@R7e0-}CCyJYCp*Dt?1ocggNZG&=(ZmW~YYW+jZ< z>xk@D&Mnp?^%|-WQ`w;~gsywXj9o-wd=55Wer)=3uyNETf6sa%B4ywUM=G+&exf;E z!P^&n2Jx2Ga1S^;6jqiygPd3IwN(ZQwe?kuj0qM;#lCk@CHKH+f% zlw`)ylIL>l{FF=RM)iqVX=zYh+zouAYh#hHTN3F6}uftt(iHBT;#$Ui6ho}_+ zE5oRvL)cr9wqxT%@eUR2>~7N`HQ*2{g2uv*u}&$abt`!Ag$Sj~*G|IYFfH*9#oowK z0Aq%>iK(Lp&}`;OY~T~)MLQk*3{WD98})=K6RMzk=7=e=7)dd{ScK3uUy!u?Tvre` zQd#;P>-LmAI*GZ9Z%3I)i*Q@u0G{6&R@)~uHh-5>Hm{nn)nrgrovVq8{kq{ajXa4v z_5C)je~O_9f<<3XSsZ@CV#6z9mX^@$)06Mzy?CURLuR*!vGmi1s@)8qAWN73ZNtib z4aesdZQIYvsAv<@J5_18qd}jUT%xw3xGSiNd#{6Gf^~8e*h)=%f(7Slquv$6U}0_G z4ZVg|@i#Z0bmom$S}gTFQ2AN-q#4%Y85lYD-fSOK<-LKm5CT1ZzqkM3jqv`*8{uI4 zSDQwV>~Cmz*8#;l;OYcDV$-j1sv;QF{deQHJ!|WZz5sB1tE0c2G)$m%4E-OPJ@JC- ze*gBSI5_^L)j+cNQ3mR!;#ewcP;pcZFNhHCRqzQW2kH!16HSi|{s(Qz`?t3Ir->AB zIE5bRFaAG5AR3U05^PkdL2?#VJYsAyT3{uGq+`=^KwDhXNSG@JcHfS{+R&z$;&ZGE1gn@JVJ)Xn>tI z2PXj{Y!AVqnURIfr&h7+T-A^BwP@C=;B2!6F;{+y>$8D}0XREb%Sz}(I7GA|KpSN! zg@g?I?v|r3xB$F8<~J9u+JTsrensT%8s(B=jImHeCg+x5Uj%R?O>5c9iY8 ztZ=Mbv$)t_y9U(5LyKj|%YcjKpMv_b16ApbvS37~kO zpT>0g?}s@?p-A>$M^RX#YV^1sgbXAN`FKX(oI zKbL(qM?SsB`TNo~`wrc#WF~V*$00UFJWip ze(l)=DQh1wBPI(XGYag-p2Raf-Ya+1mwNd`Mtzeh+Oq11Yc_2^|Jc#k9W+0$dOyr_ zBjT#<1#N(M+ec_GSNDq}Lx<^E1A8P&#|EQr)V`5?S?!;tVFsfX9Il$}--#ZdvMOIY zWXTrzp2;CLqkb4AE6!-|nJMz!RM3Uz2!63RQk?N@@?ecVbtpQG_yi=o#L)9?p=Iqj z@`N4wJn`k2yM5_8_^`DLDbajES%0%PDS+@ruNnnVe)h=R*jrit+FbeAm;`Eji0W(L zA;YgX{UhtAMdwl%J8u0i!nCsJ_PU-Q?<*U2%skNriW(|^*-p1f+#cTO#HMtm?misdtYfT8(k$=fo`84cPd$D}VMwDHw8qT_7Et*938V z#G=;*K%7<+K7*y@l^8Ee%$t({zgvqk8z8|>iv{U$i92+SgB5w~Fjh%Ot<9~|o+PB7 zWYTWiH*>eV7Ez%77+O}fyvcEy)k(GZ?B|%x)O;Aej8ZOK(=4%b-_o<+Smmh(ZJB@y3&P(X#epHIHaw;ELgJD>+BL zHmlSgUK^u~N?xuwzc79b1>gGE0k&;!0q8FDUV-;6=FDE!QDj8jpr1$CgLy9J@ZaP zfWpJ5$}qT!iM4khZRE4aDq#@MDyQP!e+hT;G}LYt(EgRfH**TtoLhFe%A^ZaFPRok zCsD@9w!@O%$Y z6JnH16NTko$M8L!AtkiX#Q29-@Lb>m7oc9{JBh72mkOLk{fyPwumx)9CyM!q1>)V^ zNIQBpBF$V z(#5@y|GfU=Gfd;7iKw5~x~>k?gr{-q7@1g$_OE#pC>R0nBga%X7+`ODN0~9iFMCtt zv}JpH`~k#=dC<%G3I4+ zT!X3~AQE)h4E7M5FMeOWXj<7)lPzJGu)J}Yo9~!opE!+HxTV`3Eeoa zlnHa4;LuAmGS?@;L&CSLXx5*Ew$L+vr8s`a38$C z)-dF1&)l$5Etxw6od$-_?iVCbRJ15Z{}@2LfAETV|MrUi(}oiC3q*NH)r6N#gHl@ zVvpbjo}{MU|75-Z9caom|8aG63;m6)6xA4(a&A_bYgzR ztU{~I+ofb0Fo&?QKQu3cU1ru(Rgk_r3=!oWxu6B{aR?V~&;V&)w|su^B7;V$NzYz3 zBW^Gj9%O(pvUft!Pyx(kMcdGp&}R2K!{WHA*s^fV{?Uh-dK zumIB7+Q);5U(r}3xqFu(ptUk2Es^CSNZx@ABONo}(C`{gOl*kl(1@_|M$u32XeRk2 zAhrjfK$a2q5+jAW1KEFl7MuggEkCAGb0}!dwPf?yv`*Vl{Fbt!&nbZ*GmV^X?WTAy z*;UZw;Zbvc5vmt49=WDbR4fCuSd52%cIAYgR3+StNB&=S@`1A5K&Ddo|8rQCK?fb3xOMt>gXMVOaOdO@l~w^Tjlh^vDnf|%7+`rR6)sV- zcDyw;SP|G1Tp2=wzAgliiyX{IvI|RbqU$3baI2Jx07K2X)Zy-a)>)uat%)zD&retz zh*Czy1kM8#ETa+vj7?Lm=dbT&gY66Qg0< zlA4K8;vb$U!lNmGB5hu9<~w6t+@Z=p5%owcZ+kVUdG3-{=_NXiV^S(wx?C*dpRbY1 zTvszoD%JMrI(wsn1ij0P_j$*_E&=P|-TI z@bIZruEUqJT1f4Lc@@Js*w*5E2jOhW9Q4GKac0@tMk@REQ+W5uy?|t%4aJIT<6@a5 zvo@M`A3@wUiJ>$?y2#oP;aP|r0SPG%KK&;*|C?3MIxK%iB2`f|EAW-Jg|8`P zOB!E{ZEsfg0ULm~ou3dlZ`CZB+3hk_L^Y{}S9*|D-9o2^F$r$Q$5Hhi2;(pco?UktKk`(8}K)zo%iSK@Mn!W~8<0FW`x`DxCg2hgpJ(6Y0q;0{@> zX?EL=!OfmG_dddnd^ZFc=E#j5qC8@VQ#nOxUsiq{4#EENa?OB@ZM{rhe*UXk%etFPm~2AeUW- zV^ZrA7Po&dSJrK#fdXfIh#`x%syf!uRlPsepCIJs>sRVm-5wNUQ%lo zItvgFzm0TF9%FXl&u_aZk*MizO0@H7F`mSPB_bm;w-m|8v#U*Nfer7o(uILftgviz z`Z$S5Vm{%bDn7|(C(BV9KI)SxXV|qq-DI@qPdb5vN8#Z!jjJ9zJq4z<)Fn;_S}H|} z%m%d*x{3PxxxyCtX2BWur<3()snh|4jgJ80)eF2R=Odvo)&=ZJ)7>COe zMe7y4wp5O7_10{S=s+BW-Ua-uVYP`&RP>GKLKEt}@4wOp1lHUi2ivc5Tb;8Hxjz6{ zZAxKIqrd&+<6k)>rdgAwE8dDqO;0JJjFPHtfEBV`&Wj5XzVE^%P4upySruTd1a%(N z6hjqWEGU8+<6LGoAS?7GBfd^Od@78(iA@UNxz*$S@Xb2iA>~9WI)hrPtj_V`DsqH1 znqJWQH7qKam=oEw!eb}EF&ARsaUdV?4UhE&#L9Qs(b+fJRzvJlk>mkvNvRV3Wvfyo zl)NJ|ZOnNZ%P_m6MIfXLHC=O8N^B4PaxGCRztjI1!0*|wqzpT~c%*%mzwo_#OYhv~ z1)ASMh~kjD4O+78oS53D^*!7~Tr} z

    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

    TT%T^R|Dqg-ZM~VdCk`BM|BVu{-O|7s4&r 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

    pair_style lj/cut/coul/long/gpu command

    +

    pair_style lj/cut/coul/long/opt command +

    pair_style lj/cut/coul/long/tip4p command

    +

    pair_style lj/cut/coul/long/tip4p/opt command +

    Syntax:

    pair_style style args 
    diff --git a/doc/pair_lj.txt b/doc/pair_lj.txt
    index 09441a9d56..fb97f627d1 100644
    --- a/doc/pair_lj.txt
    +++ b/doc/pair_lj.txt
    @@ -19,7 +19,9 @@ pair_style lj/cut/coul/debye/cuda command :h3
     pair_style lj/cut/coul/long command :h3
     pair_style lj/cut/coul/long/cuda command :h3
     pair_style lj/cut/coul/long/gpu command :h3
    +pair_style lj/cut/coul/long/opt command :h3
     pair_style lj/cut/coul/long/tip4p command :h3
    +pair_style lj/cut/coul/long/tip4p/opt command :h3
     
     [Syntax:]
     
    
    From 4fb55e497252ba58fbdb1c01bdf6dd153c61c21b Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 16:58:05 +0000
    Subject: [PATCH 158/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7019
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/GPU/pair_cg_cmm_gpu.cpp              |  2 +-
     src/KSPACE/pair_born_coul_long.cpp       |  3 +--
     src/KSPACE/pair_buck_coul_long.cpp       |  3 +--
     src/KSPACE/pair_lj_cut_coul_long_tip4p.h |  4 ++--
     src/OPT/Install.sh                       |  8 ++++++++
     src/OPT/Package.sh                       | 12 ++++++++++++
     src/USER-MISC/fix_imd.cpp                |  2 +-
     src/pair_buck_coul_cut.cpp               |  6 +++---
     8 files changed, 29 insertions(+), 11 deletions(-)
    
    diff --git a/src/GPU/pair_cg_cmm_gpu.cpp b/src/GPU/pair_cg_cmm_gpu.cpp
    index b7f7ccd330..c26cd37f5f 100644
    --- a/src/GPU/pair_cg_cmm_gpu.cpp
    +++ b/src/GPU/pair_cg_cmm_gpu.cpp
    @@ -126,7 +126,7 @@ void PairCGCMMGPU::init_style()
       cut_respa = NULL;
     
       if (force->newton_pair) 
    -    error->all(FLERR,"Cannot use newton pair with GPU CGCMM pair style");
    +    error->all(FLERR,"Cannot use newton pair with cg/cmm/gpu pair style");
     
       // Repeat cutsq calculation because done after call to init_style
       double maxcut = -1.0;
    diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp
    index 44f3d73bf9..dca8532d35 100644
    --- a/src/KSPACE/pair_born_coul_long.cpp
    +++ b/src/KSPACE/pair_born_coul_long.cpp
    @@ -122,9 +122,9 @@ void PairBornCoulLong::compute(int eflag, int vflag)
     
           if (rsq < cutsq[itype][jtype]) {
     	r2inv = 1.0/rsq;
    +	r = sqrt(rsq);
     
     	if (rsq < cut_coulsq) {
    -	  r = sqrt(rsq);
     	  grij = g_ewald * r;
     	  expm2 = exp(-grij*grij);
     	  t = 1.0 / (1.0 + EWALD_P*grij);
    @@ -136,7 +136,6 @@ void PairBornCoulLong::compute(int eflag, int vflag)
     
     	if (rsq < cut_ljsq[itype][jtype]) {
     	  r6inv = r2inv*r2inv*r2inv;
    -          r = sqrt(rsq);
     	  rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
     	  forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
     	    + born3[itype][jtype]*r2inv*r6inv;
    diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp
    index 6b3e92b50d..813b3b025a 100644
    --- a/src/KSPACE/pair_buck_coul_long.cpp
    +++ b/src/KSPACE/pair_buck_coul_long.cpp
    @@ -115,9 +115,9 @@ void PairBuckCoulLong::compute(int eflag, int vflag)
     
           if (rsq < cutsq[itype][jtype]) {
     	r2inv = 1.0/rsq;
    +	r = sqrt(rsq);
     
     	if (rsq < cut_coulsq) {
    -	  r = sqrt(rsq);
     	  grij = g_ewald * r;
     	  expm2 = exp(-grij*grij);
     	  t = 1.0 / (1.0 + EWALD_P*grij);
    @@ -129,7 +129,6 @@ void PairBuckCoulLong::compute(int eflag, int vflag)
     
     	if (rsq < cut_ljsq[itype][jtype]) {
     	  r6inv = r2inv*r2inv*r2inv;
    -          r = sqrt(rsq);
     	  rexp = exp(-r*rhoinv[itype][jtype]);
     	  forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
     	} else forcebuck = 0.0;
    diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.h b/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
    index fb660b7176..2206e0c93b 100644
    --- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
    +++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
    @@ -27,14 +27,14 @@ namespace LAMMPS_NS {
     class PairLJCutCoulLongTIP4P : public PairLJCutCoulLong {
      public:
       PairLJCutCoulLongTIP4P(class LAMMPS *);
    -  void compute(int, int);
    +  virtual void compute(int, int);
       void settings(int, char **);
       void init_style();
       void write_restart_settings(FILE *fp);
       void read_restart_settings(FILE *fp);
       void *extract(char *, int &);
     
    - private:
    + protected:
       int typeH,typeO;             // atom types of TIP4P water H and O atoms
       int typeA,typeB;             // angle and bond types of TIP4P water
       double qdist;                // distance from O site to negative charge
    diff --git a/src/OPT/Install.sh b/src/OPT/Install.sh
    index c3a413fa8c..a4005e74ea 100644
    --- a/src/OPT/Install.sh
    +++ b/src/OPT/Install.sh
    @@ -15,6 +15,10 @@ if (test $1 = 1) then
       if (test -e ../pair_lj_charmm_coul_long.cpp) then
         cp pair_lj_charmm_coul_long_opt.cpp ..
         cp pair_lj_charmm_coul_long_opt.h ..
    +    cp pair_lj_cut_coul_long_opt.cpp ..
    +    cp pair_lj_cut_coul_long_opt.h ..
    +    cp pair_lj_cut_coul_long_tip4p_opt.cpp ..
    +    cp pair_lj_cut_coul_long_tip4p_opt.h ..
       fi
     
       cp pair_lj_cut_opt.cpp ..
    @@ -29,6 +33,8 @@ elif (test $1 = 0) then
       rm -f ../pair_eam_alloy_opt.cpp
       rm -f ../pair_eam_fs_opt.cpp
       rm -f ../pair_lj_charmm_coul_long_opt.cpp
    +  rm -f ../pair_lj_cut_coul_long_opt.cpp
    +  rm -f ../pair_lj_cut_coul_long_tip4p_opt.cpp
       rm -f ../pair_lj_cut_opt.cpp
       rm -f ../pair_morse_opt.cpp
     
    @@ -36,6 +42,8 @@ elif (test $1 = 0) then
       rm -f ../pair_eam_alloy_opt.h
       rm -f ../pair_eam_fs_opt.h
       rm -f ../pair_lj_charmm_coul_long_opt.h
    +  rm -f ../pair_lj_cut_coul_long_opt.h
    +  rm -f ../pair_lj_cut_coul_long_tip4p_opt.h
       rm -f ../pair_lj_cut_opt.h
       rm -f ../pair_morse_opt.h
     
    diff --git a/src/OPT/Package.sh b/src/OPT/Package.sh
    index a822239950..a1714684fc 100644
    --- a/src/OPT/Package.sh
    +++ b/src/OPT/Package.sh
    @@ -27,6 +27,18 @@ for file in *.cpp *.h; do
       if (test $file = pair_lj_charmm_coul_long_opt.h -a ! -e ../pair_lj_charmm_coul_long.cpp) then
         continue
       fi
    +  if (test $file = pair_lj_cut_coul_long_opt.cpp -a ! -e ../pair_lj_cut_coul_long.cpp) then
    +    continue
    +  fi
    +  if (test $file = pair_lj_cut_coul_long_opt.h -a ! -e ../pair_lj_cut_coul_long.cpp) then
    +    continue
    +  fi
    +  if (test $file = pair_lj_cut_coul_long_tip4p_opt.cpp -a ! -e ../pair_lj_cut_coul_long_tip4p.cpp) then
    +    continue
    +  fi
    +  if (test $file = pair_lj_cut_coul_long_tip4p_opt.h -a ! -e ../pair_lj_cut_coul_long_tip4p.cpp) then
    +    continue
    +  fi
     
       if (test ! -e ../$file) then
         echo "  creating src/$file"
    diff --git a/src/USER-MISC/fix_imd.cpp b/src/USER-MISC/fix_imd.cpp
    index 25b140318d..462883a207 100644
    --- a/src/USER-MISC/fix_imd.cpp
    +++ b/src/USER-MISC/fix_imd.cpp
    @@ -1234,7 +1234,7 @@ void *imdsock_accept(void * v) {
     #elif defined(SOCKLEN_T)
       SOCKLEN_T len;
     #define _SOCKLEN_TYPE SOCKLEN_T
    -#elif defined(_POSIX_SOURCE)
    +#elif defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || defined(__linux)
       socklen_t len;
     #define _SOCKLEN_TYPE socklen_t
     #else
    diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp
    index 66a187ae1a..51c179b889 100644
    --- a/src/pair_buck_coul_cut.cpp
    +++ b/src/pair_buck_coul_cut.cpp
    @@ -110,14 +110,14 @@ void PairBuckCoulCut::compute(int eflag, int vflag)
     
           if (rsq < cutsq[itype][jtype]) {
     	r2inv = 1.0/rsq;
    +        r = sqrt(rsq);
     
     	if (rsq < cut_coulsq[itype][jtype])
    -	  forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
    +	  forcecoul = qqrd2e * qtmp*q[j]/r;
     	else forcecoul = 0.0;
     
     	if (rsq < cut_ljsq[itype][jtype]) {
     	  r6inv = r2inv*r2inv*r2inv;
    -          r = sqrt(rsq);
     	  rexp = exp(-r*rhoinv[itype][jtype]);
     	  forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
     	} else forcebuck = 0.0;
    @@ -135,7 +135,7 @@ void PairBuckCoulCut::compute(int eflag, int vflag)
     
     	if (eflag) {
     	  if (rsq < cut_coulsq[itype][jtype])
    -	    ecoul = factor_coul * qqrd2e * qtmp*q[j]*sqrt(r2inv);
    +	    ecoul = factor_coul * qqrd2e * qtmp*q[j]/r;
     	  else ecoul = 0.0;
     	  if (rsq < cut_ljsq[itype][jtype]) {
     	    evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
    
    From dd35394165d7f391a1baf2d62c7b9930b367c5b1 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 16:58:16 +0000
    Subject: [PATCH 159/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7020
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/OPT/pair_lj_cut_coul_long_opt.cpp       | 203 ++++++++
     src/OPT/pair_lj_cut_coul_long_opt.h         |  41 ++
     src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp | 483 ++++++++++++++++++++
     src/OPT/pair_lj_cut_coul_long_tip4p_opt.h   |  50 ++
     4 files changed, 777 insertions(+)
     create mode 100644 src/OPT/pair_lj_cut_coul_long_opt.cpp
     create mode 100644 src/OPT/pair_lj_cut_coul_long_opt.h
     create mode 100644 src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
     create mode 100644 src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
    
    diff --git a/src/OPT/pair_lj_cut_coul_long_opt.cpp b/src/OPT/pair_lj_cut_coul_long_opt.cpp
    new file mode 100644
    index 0000000000..da09305270
    --- /dev/null
    +++ b/src/OPT/pair_lj_cut_coul_long_opt.cpp
    @@ -0,0 +1,203 @@
    +/* ----------------------------------------------------------------------
    +   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 "pair_lj_cut_coul_long_opt.h"
    +#include "atom.h"
    +#include "force.h"
    +#include "neigh_list.h"
    +
    +using namespace LAMMPS_NS;
    +
    +#define EWALD_F   1.12837917
    +#define EWALD_P   0.3275911
    +#define A1        0.254829592
    +#define A2       -0.284496736
    +#define A3        1.421413741
    +#define A4       -1.453152027
    +#define A5        1.061405429
    +
    +/* ---------------------------------------------------------------------- */
    +
    +PairLJCutCoulLongOpt::PairLJCutCoulLongOpt(LAMMPS *lmp) : PairLJCutCoulLong(lmp)
    +{
    +  respa_enable = 0;
    +}
    +
    +/* ---------------------------------------------------------------------- */
    +
    +void PairLJCutCoulLongOpt::compute(int eflag, int vflag)
    +{
    +  if (eflag || vflag) ev_setup(eflag,vflag);
    +  else evflag = vflag_fdotr = 0;
    +
    +  if (!ncoultablebits) {
    +    if (evflag) {
    +      if (eflag) {
    +        if (force->newton_pair) return eval<1,1,1,0>();
    +        else return eval<1,1,0,0>();
    +      } else {
    +        if (force->newton_pair) return eval<1,0,1,0>();
    +        else return eval<1,0,0,0>();
    +      }
    +    } else {
    +      if (force->newton_pair) return eval<0,0,1,0>();
    +      else return eval<0,0,0,0>();
    +    }
    +  } else {
    +    if (evflag) {
    +      if (eflag) {
    +        if (force->newton_pair) return eval<1,1,1,1>();
    +        else return eval<1,1,0,1>();
    +      } else {
    +        if (force->newton_pair) return eval<1,0,1,1>();
    +        else return eval<1,0,0,1>();
    +      }
    +    } else {
    +      if (force->newton_pair) return eval<0,0,1,1>();
    +      else return eval<0,0,0,1>();
    +    }
    +  }
    +}
    +
    +
    +template < const int EVFLAG, const int EFLAG,
    +           const int NEWTON_PAIR, const int CTABLE >
    +void PairLJCutCoulLongOpt::eval()
    +{
    +  int i,ii,j,jj,inum,jnum,itype,jtype,itable;
    +  double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
    +  double fraction,table;
    +  double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
    +  double grij,expm2,prefactor,t,erfc;
    +  int *ilist,*jlist,*numneigh,**firstneigh;
    +  double rsq;
    +
    +  evdwl = ecoul = 0.0;
    +
    +  double **x = atom->x;
    +  double **f = atom->f;
    +  double *q = atom->q;
    +  int *type = atom->type;
    +  int nlocal = atom->nlocal;
    +  double *special_coul = force->special_coul;
    +  double *special_lj = force->special_lj;
    +  double qqrd2e = force->qqrd2e;
    +  double fxtmp,fytmp,fztmp;
    +
    +  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];
    +    fxtmp = fytmp = fztmp = 0.0;
    +
    +    for (jj = 0; jj < jnum; jj++) {
    +      j = jlist[jj];
    +      factor_lj = special_lj[sbmask(j)];
    +      factor_coul = special_coul[sbmask(j)];
    +      j &= NEIGHMASK;
    +
    +      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;
    +
    +	if (rsq < cut_coulsq) {
    +	  if (!CTABLE || rsq <= tabinnersq) {
    +	    r = sqrt(rsq);
    +	    grij = g_ewald * r;
    +	    expm2 = exp(-grij*grij);
    +	    t = 1.0 / (1.0 + EWALD_P*grij);
    +	    erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
    +	    prefactor = qqrd2e * qtmp*q[j]/r;
    +	    forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
    +	    if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
    +	  } else {
    +	    union_int_float_t rsq_lookup;
    +	    rsq_lookup.f = rsq;
    +	    itable = rsq_lookup.i & ncoulmask;
    +	    itable >>= ncoulshiftbits;
    +	    fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
    +	    table = ftable[itable] + fraction*dftable[itable];
    +	    forcecoul = qtmp*q[j] * table;
    +	    if (factor_coul < 1.0) {
    +	      table = ctable[itable] + fraction*dctable[itable];
    +	      prefactor = qtmp*q[j] * table;
    +	      forcecoul -= (1.0-factor_coul)*prefactor;
    +	    }
    +	  }
    +	} else forcecoul = 0.0;
    +
    +	if (rsq < cut_ljsq[itype][jtype]) {
    +	  r6inv = r2inv*r2inv*r2inv;
    +	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
    +	} else forcelj = 0.0;
    +
    +	fpair = (forcecoul + factor_lj*forcelj) * r2inv;
    +
    +	fxtmp += delx*fpair;
    +	fytmp += dely*fpair;
    +	fztmp += delz*fpair;
    +	if (NEWTON_PAIR || j < nlocal) {
    +	  f[j][0] -= delx*fpair;
    +	  f[j][1] -= dely*fpair;
    +	  f[j][2] -= delz*fpair;
    +	}
    +
    +	if (EFLAG) {
    +	  if (rsq < cut_coulsq) {
    +	    if (!CTABLE || rsq <= tabinnersq)
    +	      ecoul = prefactor*erfc;
    +	    else {
    +	      table = etable[itable] + fraction*detable[itable];
    +	      ecoul = qtmp*q[j] * table;
    +	    }
    +	    if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
    +	  } else ecoul = 0.0;
    +
    +	  if (rsq < cut_ljsq[itype][jtype]) {
    +	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
    +	      offset[itype][jtype];
    +	    evdwl *= factor_lj;
    +	  } else evdwl = 0.0;
    +	}
    +
    +	if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
    +			     evdwl,ecoul,fpair,delx,dely,delz);
    +      }
    +    }
    +    f[i][0] += fxtmp;
    +    f[i][1] += fytmp;
    +    f[i][2] += fztmp;
    +  }
    +
    +  if (vflag_fdotr) virial_fdotr_compute();
    +}
    +
    +/* ---------------------------------------------------------------------- */
    diff --git a/src/OPT/pair_lj_cut_coul_long_opt.h b/src/OPT/pair_lj_cut_coul_long_opt.h
    new file mode 100644
    index 0000000000..4c19ee9b5d
    --- /dev/null
    +++ b/src/OPT/pair_lj_cut_coul_long_opt.h
    @@ -0,0 +1,41 @@
    +/* ----------------------------------------------------------------------
    +   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.
    +------------------------------------------------------------------------- */
    +
    +#ifdef PAIR_CLASS
    +
    +PairStyle(lj/cut/coul/long/opt,PairLJCutCoulLongOpt)
    +
    +#else
    +
    +#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OPT_H
    +#define LMP_PAIR_LJ_CUT_COUL_LONG_OPT_H
    +
    +#include "pair_lj_cut_coul_long.h"
    +
    +namespace LAMMPS_NS {
    +
    +class PairLJCutCoulLongOpt : public PairLJCutCoulLong {
    + public:
    +  PairLJCutCoulLongOpt(class LAMMPS *);
    +  virtual void compute(int, int);
    +
    + protected:
    +  template 
    +  void eval();
    +};
    +
    +}
    +
    +#endif
    +#endif
    diff --git a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
    new file mode 100644
    index 0000000000..24db63e579
    --- /dev/null
    +++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
    @@ -0,0 +1,483 @@
    +/* ----------------------------------------------------------------------
    +   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.
    +------------------------------------------------------------------------- */
    +
    +/* ----------------------------------------------------------------------
    +   OPT version: Axel Kohlmeyer (Temple U)
    +------------------------------------------------------------------------- */
    +
    +#include "math.h"
    +#include "pair_lj_cut_coul_long_tip4p_opt.h"
    +#include "atom.h"
    +#include "domain.h"
    +#include "force.h"
    +#include "error.h"
    +#include "memory.h"
    +#include "neigh_list.h"
    +
    +using namespace LAMMPS_NS;
    +
    +#define EWALD_F   1.12837917
    +#define EWALD_P   0.3275911
    +#define A1        0.254829592
    +#define A2       -0.284496736
    +#define A3        1.421413741
    +#define A4       -1.453152027
    +#define A5        1.061405429
    +
    +/* ---------------------------------------------------------------------- */
    +
    +PairLJCutCoulLongTIP4POpt::PairLJCutCoulLongTIP4POpt(LAMMPS *lmp) :
    +  PairLJCutCoulLongTIP4P(lmp)
    +{
    +  single_enable = 0;
    +  respa_enable = 0;
    +
    +  // TIP4P cannot compute virial as F dot r
    +  // due to find_M() finding bonded H atoms which are not near O atom
    +
    +  no_virial_fdotr_compute = 1;
    +
    +  // for caching m-shift corrected positions
    +  maxmpos = 0;
    +  h1idx = h2idx = NULL;
    +  mpos = NULL;
    +}
    +
    +PairLJCutCoulLongTIP4POpt::~PairLJCutCoulLongTIP4POpt()
    +{
    +  memory->destroy(h1idx);
    +  memory->destroy(h2idx);
    +  memory->destroy(mpos);
    +}
    +
    +void PairLJCutCoulLongTIP4POpt::compute(int eflag, int vflag)
    +{
    +  if (eflag || vflag) ev_setup(eflag,vflag);
    +  else evflag = vflag_fdotr = 0;
    +
    +  const int nlocal = atom->nlocal;
    +  const int nall = nlocal + atom->nghost;
    +
    +  // reallocate per-atom arrays, if necessary
    +  if (nall > maxmpos) {
    +    maxmpos = nall;
    +    memory->grow(mpos,maxmpos,3,"pair:mpos");
    +    memory->grow(h1idx,maxmpos,"pair:h1idx");
    +    memory->grow(h2idx,maxmpos,"pair:h2idx");
    +  }
    +
    +  // cache corrected M positions in mpos[]
    +  double **x = atom->x;
    +  int *type = atom->type;
    +  for (int i = 0; i < nlocal; i++) {
    +    if (type[i] == typeO) {
    +      find_M(i,h1idx[i],h2idx[i],mpos[i]);
    +    } else {
    +      mpos[i][0] = x[i][0];
    +      mpos[i][1] = x[i][1];
    +      mpos[i][2] = x[i][2];
    +    }
    +  }
    +  for (int i = nlocal; i < nall; i++) {
    +    if (type[i] == typeO) {
    +      find_M_permissive(i,h1idx[i],h2idx[i],mpos[i]);
    +    } else {
    +      mpos[i][0] = x[i][0];
    +      mpos[i][1] = x[i][1];
    +      mpos[i][2] = x[i][2];
    +    }
    +  }
    +
    +  if (!ncoultablebits) {
    +    if (evflag) {
    +      if (eflag) {
    +	if (vflag) {
    +	  if (force->newton_pair) return eval<1,1,1,1,0>();
    +	  else return eval<1,1,1,0,0>();
    +	} else {
    +	  if (force->newton_pair) return eval<1,1,0,1,0>();
    +	  else return eval<1,1,0,0,0>();
    +	} 
    +      } else {
    +	if (vflag) {
    +	  if (force->newton_pair) return eval<1,0,1,1,0>();
    +	  else return eval<1,0,1,0,0>();
    +	} else {
    +	  if (force->newton_pair) return eval<1,0,0,1,0>();
    +	  else return eval<1,0,0,0,0>();
    +	}
    +      }
    +    } else {
    +      if (force->newton_pair) return eval<0,0,0,1,0>();
    +      else return eval<0,0,0,0,0>();
    +    }
    +  } else {
    +    if (evflag) {
    +      if (eflag) {
    +	if (vflag) {
    +	  if (force->newton_pair) return eval<1,1,1,1,1>();
    +	  else return eval<1,1,1,0,1>();
    +	} else {
    +	  if (force->newton_pair) return eval<1,1,0,1,1>();
    +	  else return eval<1,1,0,0,1>();
    +	}
    +      } else {
    +	if (vflag) {
    +	  if (force->newton_pair) return eval<1,0,1,1,1>();
    +	  else return eval<1,0,1,0,1>();
    +	} else {
    +	  if (force->newton_pair) return eval<1,0,0,1,1>();
    +	  else return eval<1,0,0,0,1>();
    +	}
    +      }
    +    } else {
    +      if (force->newton_pair) return eval<0,0,0,1,1>();
    +      else return eval<0,0,0,0,1>();
    +    }
    +  }
    +}
    +
    +/* ---------------------------------------------------------------------- */
    +
    +template < const int EVFLAG, const int EFLAG, const int VFLAG,
    +           const int NEWTON_PAIR, const int CTABLE >
    +void PairLJCutCoulLongTIP4POpt::eval()
    +{
    +  int i,j,ii,jj,inum,jnum,itype,jtype,itable;
    +  int n,vlist[6];
    +  int iH1,iH2,jH1,jH2;
    +  double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
    +  double fraction,table;
    +  double delxOM, delyOM, delzOM;
    +  double r,r2inv,r6inv,forcecoul,forcelj,cforce;
    +  double factor_coul,factor_lj;
    +  double grij,expm2,prefactor,t,erfc,ddotf;
    +  double xiM[3],xjM[3],v[6],xH1[3],xH2[3];
    +  double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz;
    +  double *x1,*x2;
    +  int *ilist,*jlist,*numneigh,**firstneigh;
    +  double rsq;
    +
    +  evdwl = ecoul = 0.0;
    +
    +  double **f = atom->f;
    +  double **x = atom->x;
    +  double *q = atom->q;
    +  int *type = atom->type;
    +  int nlocal = atom->nlocal;
    +  double *special_coul = force->special_coul;
    +  double *special_lj = force->special_lj;
    +  int newton_pair = force->newton_pair;
    +  double qqrd2e = force->qqrd2e;
    +  double fxtmp,fytmp,fztmp;
    +
    +  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];
    +    fxtmp=fytmp=fztmp=0.0;
    +    x1 = mpos[i];
    +    iH1 = h1idx[i];
    +    iH2 = h2idx[i];
    +
    +    for (jj = 0; jj < jnum; jj++) {
    +      j = jlist[jj];
    +      factor_lj = special_lj[sbmask(j)];
    +      factor_coul = special_coul[sbmask(j)];
    +      j &= NEIGHMASK;
    +
    +      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;
    +
    +	if (rsq < cut_ljsq[itype][jtype]) {
    +	  r6inv = r2inv*r2inv*r2inv;
    +	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
    +	  forcelj *= factor_lj * r2inv;
    +
    +	  fxtmp += delx*forcelj;
    +	  fytmp += dely*forcelj;
    +	  fztmp += delz*forcelj;
    +	  f[j][0] -= delx*forcelj;
    +	  f[j][1] -= dely*forcelj;
    +	  f[j][2] -= delz*forcelj;
    +
    +	  if (EFLAG) {
    +	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
    +	      offset[itype][jtype];
    +	    evdwl *= factor_lj;
    +	  } else evdwl = 0.0;
    +
    +	  if (EVFLAG) ev_tally(i,j,nlocal,newton_pair,
    +			       evdwl,0.0,forcelj,delx,dely,delz);
    +	}
    +
    +	// adjust rsq and delxyz for off-site O charge(s)
    +
    +	if (itype == typeO || jtype == typeO) {
    +	  x2 = mpos[j];
    +	  jH1 = h1idx[j];
    +	  jH2 = h2idx[j];
    +	  if (jtype == typeO && ( jH1 < 0 || jH2 < 0))
    +	    error->one(FLERR,"TIP4P hydrogen is missing");
    +	  delx = x1[0] - x2[0];
    +	  dely = x1[1] - x2[1];
    +	  delz = x1[2] - x2[2];
    +	  rsq = delx*delx + dely*dely + delz*delz;
    +	}
    +
    +	// test current rsq against cutoff and compute Coulombic force
    +
    +	if (rsq < cut_coulsq) {
    +	  r2inv = 1 / rsq;
    +	  if (!CTABLE || rsq <= tabinnersq) {
    +	    r = sqrt(rsq);
    +	    grij = g_ewald * r;
    +	    expm2 = exp(-grij*grij);
    +	    t = 1.0 / (1.0 + EWALD_P*grij);
    +	    erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
    +	    prefactor = qqrd2e * qtmp*q[j]/r;
    +	    forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
    +	    if (factor_coul < 1.0) {
    +	      forcecoul -= (1.0-factor_coul)*prefactor; 
    +	    }
    +	  } else {
    +	    union_int_float_t rsq_lookup;
    +	    rsq_lookup.f = rsq;
    +	    itable = rsq_lookup.i & ncoulmask;
    +	    itable >>= ncoulshiftbits;
    +	    fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
    +	    table = ftable[itable] + fraction*dftable[itable];
    +	    forcecoul = qtmp*q[j] * table;
    +	    if (factor_coul < 1.0) {
    +	      table = ctable[itable] + fraction*dctable[itable];
    +	      prefactor = qtmp*q[j] * table;
    +	      forcecoul -= (1.0-factor_coul)*prefactor;
    +	    }
    +	  }
    +
    +	  cforce = forcecoul * r2inv;
    +
    +	  // if i,j are not O atoms, force is applied directly
    +	  // if i or j are O atoms, force is on fictitious atom & partitioned
    +	  // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
    +	  // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
    +	  // preserves total force and torque on water molecule
    +	  // virial = sum(r x F) where each water's atoms are near xi and xj
    +	  // vlist stores 2,4,6 atoms whose forces contribute to virial
    +
    +	  n = 0;
    +
    +	  if (itype != typeO) {
    +	    fxtmp += delx * cforce;
    +	    fytmp += dely * cforce;
    +	    fztmp += delz * cforce;
    +
    +	    if (VFLAG) {
    +	      v[0] = x[i][0] * delx * cforce;
    +	      v[1] = x[i][1] * dely * cforce;
    +	      v[2] = x[i][2] * delz * cforce;
    +	      v[3] = x[i][0] * dely * cforce;
    +	      v[4] = x[i][0] * delz * cforce;
    +	      v[5] = x[i][1] * delz * cforce;
    +	      vlist[n++] = i;
    +	    }
    +
    +	  } else {
    +
    +            fdx = delx*cforce;
    +            fdy = dely*cforce;
    +            fdz = delz*cforce;
    +
    +            delxOM = x[i][0] - x1[0];
    +            delyOM = x[i][1] - x1[1];
    +            delzOM = x[i][2] - x1[2];
    +
    +            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
    +	      (qdist*qdist);
    +
    +	    f1x = alpha * (fdx - ddotf * delxOM);
    +	    f1y = alpha * (fdy - ddotf * delyOM);
    +	    f1z = alpha * (fdz - ddotf * delzOM);
    +
    +            fOx = fdx - f1x;
    +            fOy = fdy - f1y;
    +            fOz = fdz - f1z;
    +
    +            fHx = 0.5 * f1x;
    +            fHy = 0.5 * f1y;
    +            fHz = 0.5 * f1z;
    +
    +            fxtmp += fOx;
    +            fytmp += fOy;
    +            fztmp += fOz;
    +
    +            f[iH1][0] += fHx;
    +            f[iH1][1] += fHy;
    +            f[iH1][2] += fHz;
    +
    +            f[iH2][0] += fHx;
    +            f[iH2][1] += fHy;
    +            f[iH2][2] += fHz;
    +
    +	    if (VFLAG) {
    +	      domain->closest_image(x[i],x[iH1],xH1);
    +	      domain->closest_image(x[i],x[iH2],xH2);
    +
    +	      v[0] = x[i][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
    +	      v[1] = x[i][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
    +	      v[2] = x[i][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
    +	      v[3] = x[i][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
    +	      v[4] = x[i][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
    +	      v[5] = x[i][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
    +
    +	      vlist[n++] = i;
    +	      vlist[n++] = iH1;
    +	      vlist[n++] = iH2;
    +	    }
    +	  }
    +
    +	  if (jtype != typeO) {
    +	    f[j][0] -= delx * cforce;
    +	    f[j][1] -= dely * cforce;
    +	    f[j][2] -= delz * cforce;
    +
    +	    if (VFLAG) {
    +	      v[0] -= x[j][0] * delx * cforce;
    +	      v[1] -= x[j][1] * dely * cforce;
    +	      v[2] -= x[j][2] * delz * cforce;
    +	      v[3] -= x[j][0] * dely * cforce;
    +	      v[4] -= x[j][0] * delz * cforce;
    +	      v[5] -= x[j][1] * delz * cforce;
    +	      vlist[n++] = j;
    +	    }
    +
    +	  } else {
    +
    +	    fdx = -delx*cforce;
    +	    fdy = -dely*cforce;
    +	    fdz = -delz*cforce;
    +
    +	    delxOM = x[j][0] - x2[0];
    +	    delyOM = x[j][1] - x2[1];
    +	    delzOM = x[j][2] - x2[2];
    +
    +            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
    +	      (qdist*qdist);
    +
    +	    f1x = alpha * (fdx - ddotf * delxOM);
    +	    f1y = alpha * (fdy - ddotf * delyOM);
    +	    f1z = alpha * (fdz - ddotf * delzOM);
    +
    +            fOx = fdx - f1x;
    +            fOy = fdy - f1y;
    +            fOz = fdz - f1z;
    +
    +            fHx = 0.5 * f1x;
    +            fHy = 0.5 * f1y;
    +            fHz = 0.5 * f1z;
    +
    +	    f[j][0] += fOx;
    +	    f[j][1] += fOy;
    +	    f[j][2] += fOz;
    +
    +            f[jH1][0] += fHx;
    +            f[jH1][1] += fHy;
    +            f[jH1][2] += fHz;
    +
    +            f[jH2][0] += fHx;
    +            f[jH2][1] += fHy;
    +            f[jH2][2] += fHz;
    +
    +	    if (VFLAG) {
    +	      domain->closest_image(x[j],x[jH1],xH1);
    +	      domain->closest_image(x[j],x[jH2],xH2);
    +
    +	      v[0] += x[j][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
    +	      v[1] += x[j][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
    +	      v[2] += x[j][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
    +	      v[3] += x[j][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
    +	      v[4] += x[j][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
    +	      v[5] += x[j][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
    +
    +	      vlist[n++] = j;
    +	      vlist[n++] = jH1;
    +	      vlist[n++] = jH2;
    +	    }
    +	  }
    +
    +	  if (EFLAG) {
    +	    if (!CTABLE || rsq <= tabinnersq)
    +	      ecoul = prefactor*erfc;
    +	    else {
    +	      table = etable[itable] + fraction*detable[itable];
    +	      ecoul = qtmp*q[j] * table;
    +	    }
    +	    if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
    +	  } else ecoul = 0.0;
    +
    +	  if (EVFLAG) ev_tally_list(n,vlist,ecoul,v);
    +	}
    +      }
    +    }
    +    f[i][0] += fxtmp;
    +    f[i][1] += fytmp;
    +    f[i][2] += fztmp;
    +  }
    +}
    +
    +/* ---------------------------------------------------------------------- */
    +
    +void PairLJCutCoulLongTIP4POpt::find_M_permissive(int i, int &iH1, int &iH2, double *xM)
    +{
    +  // test that O is correctly bonded to 2 succesive H atoms
    +
    +   iH1 = atom->map(atom->tag[i] + 1);
    +   iH2 = atom->map(atom->tag[i] + 2);
    +
    +   if (iH1 == -1 || iH2 == -1)
    +      return;
    +   else
    +      find_M(i,iH1,iH2,xM);
    +}
    +
    +/* ---------------------------------------------------------------------- */
    +
    +double PairLJCutCoulLongTIP4POpt::memory_usage()
    +{
    +  double bytes = PairLJCutCoulLongTIP4P::memory_usage();
    +  bytes += 2 * maxmpos * sizeof(int);
    +  bytes += 3 * maxmpos * sizeof(double);
    +  bytes += maxmpos * sizeof(double *);
    +
    +  return bytes;
    +}
    diff --git a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
    new file mode 100644
    index 0000000000..902ec39708
    --- /dev/null
    +++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
    @@ -0,0 +1,50 @@
    +/* -*- c++ -*- ----------------------------------------------------------
    +   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.
    +------------------------------------------------------------------------- */
    +
    +#ifdef PAIR_CLASS
    +
    +PairStyle(lj/cut/coul/long/tip4p/opt,PairLJCutCoulLongTIP4POpt)
    +
    +#else
    +
    +#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OPT_H
    +#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OPT_H
    +
    +#include "pair_lj_cut_coul_long_tip4p.h"
    +
    +namespace LAMMPS_NS {
    +
    +class PairLJCutCoulLongTIP4POpt : public PairLJCutCoulLongTIP4P {
    + public:
    +  PairLJCutCoulLongTIP4POpt(class LAMMPS *);
    +  virtual ~PairLJCutCoulLongTIP4POpt();
    +
    +  virtual void compute(int, int);
    +  virtual double memory_usage();
    +
    + protected:
    +  // this is to cache m-shift corrected positions.
    +  int maxmpos;        // size of the following arrays
    +  int *h1idx, *h2idx; // local index of hydrogen atoms
    +  double **mpos;      // coordinates corrected for m-shift.
    +  void find_M_permissive(int, int &, int &, double *);
    +
    +  template < const int, const int, const int, const int, const int >
    +  void eval();
    +
    +};
    +
    +}
    +
    +#endif
    +#endif
    
    From 79e10871461aebaf0ec122cfa2070e9d0cdef817 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 16:58:31 +0000
    Subject: [PATCH 160/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7021
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     lib/gpu/Nvidia.makefile |  2 +-
     lib/gpu/README          | 10 +++++-----
     2 files changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/lib/gpu/Nvidia.makefile b/lib/gpu/Nvidia.makefile
    index b126f3433a..49ff3fd13d 100644
    --- a/lib/gpu/Nvidia.makefile
    +++ b/lib/gpu/Nvidia.makefile
    @@ -61,7 +61,7 @@ OBJS = $(OBJ_DIR)/pair_gpu_atom.o $(OBJ_DIR)/pair_gpu_ans.o \
            $(OBJ_DIR)/cmmc_long_gpu_memory.o $(OBJ_DIR)/cmmc_long_gpu.o \
            $(OBJ_DIR)/cmmc_msm_gpu_memory.o $(OBJ_DIR)/cmmc_msm_gpu.o \
            $(CUDPP)
    -PTXS = $(OBJ_DIR)/pair_gpu_dev_kernel.ptx \
    +PTXS = $(OBJ_DIR)/pair_gpu_dev_kernel.ptx  $(OBJ_DIR)/pair_gpu_dev_ptx.h \
            $(OBJ_DIR)/pair_gpu_atom_kernel.ptx $(OBJ_DIR)/pair_gpu_atom_ptx.h \
            $(OBJ_DIR)/pair_gpu_nbor_kernel.ptx $(OBJ_DIR)/pair_gpu_nbor_ptx.h \
            $(OBJ_DIR)/pair_gpu_build_kernel.ptx $(OBJ_DIR)/pair_gpu_build_ptx.h \
    diff --git a/lib/gpu/README b/lib/gpu/README
    index 61486b0d15..7eb0d86719 100644
    --- a/lib/gpu/README
    +++ b/lib/gpu/README
    @@ -105,7 +105,8 @@ NOTE: For graphics cards with compute capability>=1.3 (e.g. Tesla C1060),
           make sure that -arch=sm_13 is set on the CUDA_ARCH line.
     
     NOTE: For newer graphics card (a.k.a. "Fermi", e.g. Tesla C2050), make 
    -      sure that -arch=sm_20 is set on the CUDA_ARCH line.
    +      sure that either -arch=sm_20 or -arch=sm_21 is set on the 
    +      CUDA_ARCH line, depending on hardware and CUDA toolkit version.
     
     NOTE: The gayberne/gpu pair style will only be installed if the ASPHERE
           package has been installed.
    @@ -114,11 +115,10 @@ NOTE: The cg/cmm/gpu and cg/cmm/coul/long/gpu pair styles will only be
           installed if the USER-CG-CMM package has been installed.
     
     NOTE: The lj/cut/coul/long/gpu, cg/cmm/coul/long/gpu, coul/long/gpu,
    -      and pppm/gpu styles will only be installed if the KSPACE package
    -      has been installed.
    +      lj/charmm/coul/long/gpu and pppm/gpu styles will only be installed
    +      if the KSPACE package has been installed.
    +
     
    -NOTE: The lj/charmm/coul/long will only be installed if the MOLECULE package
    -      has been installed.
     
                           EXAMPLE BUILD PROCESS
                         
    
    From a352cb0ed641c6d3a721b08c8b6fec461172dff2 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 17:02:34 +0000
    Subject: [PATCH 161/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7022
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/version.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/version.h b/src/version.h
    index e8f4df30ba..c571f550da 100644
    --- a/src/version.h
    +++ b/src/version.h
    @@ -1 +1 @@
    -#define LAMMPS_VERSION "29 Sep 2011"
    +#define LAMMPS_VERSION "30 Sep 2011"
    
    From f7f353f8cf1dc88c99db03254a4b194ad8094f59 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 17:46:44 +0000
    Subject: [PATCH 162/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7024
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/MAKE/Makefile.altix        | 2 +-
     src/MAKE/Makefile.bgl          | 2 +-
     src/MAKE/Makefile.cygwin       | 2 +-
     src/MAKE/Makefile.encanto      | 2 +-
     src/MAKE/Makefile.fink         | 2 +-
     src/MAKE/Makefile.g++          | 2 +-
     src/MAKE/Makefile.g++3         | 2 +-
     src/MAKE/Makefile.glory        | 2 +-
     src/MAKE/Makefile.jaguar       | 2 +-
     src/MAKE/Makefile.lam          | 2 +-
     src/MAKE/Makefile.linux        | 2 +-
     src/MAKE/Makefile.mac          | 2 +-
     src/MAKE/Makefile.mac_mpi      | 2 +-
     src/MAKE/Makefile.mingw        | 2 +-
     src/MAKE/Makefile.mkl          | 2 +-
     src/MAKE/Makefile.odin         | 2 +-
     src/MAKE/Makefile.openmpi      | 2 +-
     src/MAKE/Makefile.pgi          | 2 +-
     src/MAKE/Makefile.power5       | 2 +-
     src/MAKE/Makefile.qed          | 2 +-
     src/MAKE/Makefile.redsky       | 2 +-
     src/MAKE/Makefile.sdsc         | 2 +-
     src/MAKE/Makefile.seaborg      | 2 +-
     src/MAKE/Makefile.serial       | 2 +-
     src/MAKE/Makefile.serial_debug | 2 +-
     src/MAKE/Makefile.sgi          | 2 +-
     src/MAKE/Makefile.solaris      | 2 +-
     src/MAKE/Makefile.spirit       | 2 +-
     src/MAKE/Makefile.tacc         | 2 +-
     src/MAKE/Makefile.tbird        | 2 +-
     src/MAKE/Makefile.tesla        | 2 +-
     src/MAKE/Makefile.tunnison     | 2 +-
     src/MAKE/Makefile.xe6          | 2 +-
     src/MAKE/Makefile.xt3          | 2 +-
     src/MAKE/Makefile.xt5          | 2 +-
     35 files changed, 35 insertions(+), 35 deletions(-)
    
    diff --git a/src/MAKE/Makefile.altix b/src/MAKE/Makefile.altix
    index 47e972d2c3..1c12615c79 100644
    --- a/src/MAKE/Makefile.altix
    +++ b/src/MAKE/Makefile.altix
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.bgl b/src/MAKE/Makefile.bgl
    index dce6893600..df0e8e5032 100644
    --- a/src/MAKE/Makefile.bgl
    +++ b/src/MAKE/Makefile.bgl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.cygwin b/src/MAKE/Makefile.cygwin
    index c621df2e0f..d36456d962 100644
    --- a/src/MAKE/Makefile.cygwin
    +++ b/src/MAKE/Makefile.cygwin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.encanto b/src/MAKE/Makefile.encanto
    index 045a8f0031..e4ba3674df 100644
    --- a/src/MAKE/Makefile.encanto
    +++ b/src/MAKE/Makefile.encanto
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.fink b/src/MAKE/Makefile.fink
    index 9906bdf73c..ed7c3a1d3c 100644
    --- a/src/MAKE/Makefile.fink
    +++ b/src/MAKE/Makefile.fink
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++
    index c9e068aa86..111495e650 100755
    --- a/src/MAKE/Makefile.g++
    +++ b/src/MAKE/Makefile.g++
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++3 b/src/MAKE/Makefile.g++3
    index cbdb280820..fc84db14c0 100755
    --- a/src/MAKE/Makefile.g++3
    +++ b/src/MAKE/Makefile.g++3
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.glory b/src/MAKE/Makefile.glory
    index ed6fa3acb0..eefd561817 100644
    --- a/src/MAKE/Makefile.glory
    +++ b/src/MAKE/Makefile.glory
    @@ -110,4 +110,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.jaguar b/src/MAKE/Makefile.jaguar
    index 118ccac606..c1e80752f4 100644
    --- a/src/MAKE/Makefile.jaguar
    +++ b/src/MAKE/Makefile.jaguar
    @@ -99,4 +99,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.lam b/src/MAKE/Makefile.lam
    index f7bc330cb5..b304fb04b2 100644
    --- a/src/MAKE/Makefile.lam
    +++ b/src/MAKE/Makefile.lam
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.linux b/src/MAKE/Makefile.linux
    index 428f73709d..17231356d1 100755
    --- a/src/MAKE/Makefile.linux
    +++ b/src/MAKE/Makefile.linux
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac b/src/MAKE/Makefile.mac
    index 67a6932048..83fb667fdb 100755
    --- a/src/MAKE/Makefile.mac
    +++ b/src/MAKE/Makefile.mac
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac_mpi b/src/MAKE/Makefile.mac_mpi
    index b63d806b7a..6a6afc5e0e 100755
    --- a/src/MAKE/Makefile.mac_mpi
    +++ b/src/MAKE/Makefile.mac_mpi
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mingw b/src/MAKE/Makefile.mingw
    index 2a2202fb54..b88f8ef0fb 100644
    --- a/src/MAKE/Makefile.mingw
    +++ b/src/MAKE/Makefile.mingw
    @@ -101,4 +101,4 @@ mpi.o:  ../STUBS/mpi.c ../STUBS/mpi.h
     	$(CC) $(CCFLAGS) $(EXTRA_INC) -c $<
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mkl b/src/MAKE/Makefile.mkl
    index 83a07e20ce..e9795da540 100644
    --- a/src/MAKE/Makefile.mkl
    +++ b/src/MAKE/Makefile.mkl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.odin b/src/MAKE/Makefile.odin
    index 4ab791bcf1..4cc2f004b2 100755
    --- a/src/MAKE/Makefile.odin
    +++ b/src/MAKE/Makefile.odin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.openmpi b/src/MAKE/Makefile.openmpi
    index db9d01a821..09d15211b5 100644
    --- a/src/MAKE/Makefile.openmpi
    +++ b/src/MAKE/Makefile.openmpi
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.pgi b/src/MAKE/Makefile.pgi
    index bcfae62ec1..ab8cec3805 100644
    --- a/src/MAKE/Makefile.pgi
    +++ b/src/MAKE/Makefile.pgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.power5 b/src/MAKE/Makefile.power5
    index 12712d0a20..ac736d35c6 100644
    --- a/src/MAKE/Makefile.power5
    +++ b/src/MAKE/Makefile.power5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.qed b/src/MAKE/Makefile.qed
    index 15ff05567d..42d8b012bd 100644
    --- a/src/MAKE/Makefile.qed
    +++ b/src/MAKE/Makefile.qed
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.redsky b/src/MAKE/Makefile.redsky
    index 2323b4fc86..6da8ac017c 100644
    --- a/src/MAKE/Makefile.redsky
    +++ b/src/MAKE/Makefile.redsky
    @@ -121,4 +121,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sdsc b/src/MAKE/Makefile.sdsc
    index 0bd78adb96..5d788a8899 100644
    --- a/src/MAKE/Makefile.sdsc
    +++ b/src/MAKE/Makefile.sdsc
    @@ -97,4 +97,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.seaborg b/src/MAKE/Makefile.seaborg
    index d3fb643400..a3beccb302 100644
    --- a/src/MAKE/Makefile.seaborg
    +++ b/src/MAKE/Makefile.seaborg
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
    index 30196c40aa..b6abb9c4d7 100755
    --- a/src/MAKE/Makefile.serial
    +++ b/src/MAKE/Makefile.serial
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial_debug b/src/MAKE/Makefile.serial_debug
    index 378e3e275b..c888377c8c 100644
    --- a/src/MAKE/Makefile.serial_debug
    +++ b/src/MAKE/Makefile.serial_debug
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sgi b/src/MAKE/Makefile.sgi
    index 10a41218f4..e3b2288ad8 100644
    --- a/src/MAKE/Makefile.sgi
    +++ b/src/MAKE/Makefile.sgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.solaris b/src/MAKE/Makefile.solaris
    index 4f27651af7..0b07e8f90a 100644
    --- a/src/MAKE/Makefile.solaris
    +++ b/src/MAKE/Makefile.solaris
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.spirit b/src/MAKE/Makefile.spirit
    index 29397aafe6..700df11d62 100644
    --- a/src/MAKE/Makefile.spirit
    +++ b/src/MAKE/Makefile.spirit
    @@ -100,4 +100,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tacc b/src/MAKE/Makefile.tacc
    index 09bdf45c50..964347f50e 100644
    --- a/src/MAKE/Makefile.tacc
    +++ b/src/MAKE/Makefile.tacc
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tbird b/src/MAKE/Makefile.tbird
    index 65b34ca4a1..2df081c1e9 100644
    --- a/src/MAKE/Makefile.tbird
    +++ b/src/MAKE/Makefile.tbird
    @@ -111,4 +111,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tesla b/src/MAKE/Makefile.tesla
    index dd1e2c7b2d..514617bbfb 100755
    --- a/src/MAKE/Makefile.tesla
    +++ b/src/MAKE/Makefile.tesla
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tunnison b/src/MAKE/Makefile.tunnison
    index bbfd84c20c..cbb07fd91b 100644
    --- a/src/MAKE/Makefile.tunnison
    +++ b/src/MAKE/Makefile.tunnison
    @@ -103,4 +103,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xe6 b/src/MAKE/Makefile.xe6
    index d394809ded..e1c64a9248 100644
    --- a/src/MAKE/Makefile.xe6
    +++ b/src/MAKE/Makefile.xe6
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt3 b/src/MAKE/Makefile.xt3
    index 7017a5da81..9a17253894 100644
    --- a/src/MAKE/Makefile.xt3
    +++ b/src/MAKE/Makefile.xt3
    @@ -94,4 +94,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt5 b/src/MAKE/Makefile.xt5
    index 9fb5968191..53270d5af0 100644
    --- a/src/MAKE/Makefile.xt5
    +++ b/src/MAKE/Makefile.xt5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    -include $(DEPENDS)
    +-include $(DEPENDS)
    
    From 0df8da2f71776df5b42761b1d8ab3c8c44e507ac Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 17:48:40 +0000
    Subject: [PATCH 163/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7025
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/MAKE/Makefile.altix        | 2 +-
     src/MAKE/Makefile.bgl          | 2 +-
     src/MAKE/Makefile.cygwin       | 2 +-
     src/MAKE/Makefile.encanto      | 2 +-
     src/MAKE/Makefile.fink         | 2 +-
     src/MAKE/Makefile.g++          | 2 +-
     src/MAKE/Makefile.g++3         | 2 +-
     src/MAKE/Makefile.glory        | 2 +-
     src/MAKE/Makefile.jaguar       | 2 +-
     src/MAKE/Makefile.lam          | 2 +-
     src/MAKE/Makefile.linux        | 2 +-
     src/MAKE/Makefile.mac          | 2 +-
     src/MAKE/Makefile.mac_mpi      | 2 +-
     src/MAKE/Makefile.mingw        | 2 +-
     src/MAKE/Makefile.mkl          | 2 +-
     src/MAKE/Makefile.odin         | 2 +-
     src/MAKE/Makefile.openmpi      | 2 +-
     src/MAKE/Makefile.pgi          | 2 +-
     src/MAKE/Makefile.power5       | 2 +-
     src/MAKE/Makefile.qed          | 2 +-
     src/MAKE/Makefile.redsky       | 2 +-
     src/MAKE/Makefile.sdsc         | 2 +-
     src/MAKE/Makefile.seaborg      | 2 +-
     src/MAKE/Makefile.serial       | 2 +-
     src/MAKE/Makefile.serial_debug | 2 +-
     src/MAKE/Makefile.sgi          | 2 +-
     src/MAKE/Makefile.solaris      | 2 +-
     src/MAKE/Makefile.spirit       | 2 +-
     src/MAKE/Makefile.tacc         | 2 +-
     src/MAKE/Makefile.tbird        | 2 +-
     src/MAKE/Makefile.tesla        | 2 +-
     src/MAKE/Makefile.tunnison     | 2 +-
     src/MAKE/Makefile.xe6          | 2 +-
     src/MAKE/Makefile.xt3          | 2 +-
     src/MAKE/Makefile.xt5          | 2 +-
     35 files changed, 35 insertions(+), 35 deletions(-)
    
    diff --git a/src/MAKE/Makefile.altix b/src/MAKE/Makefile.altix
    index 1c12615c79..39d5d26779 100644
    --- a/src/MAKE/Makefile.altix
    +++ b/src/MAKE/Makefile.altix
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.bgl b/src/MAKE/Makefile.bgl
    index df0e8e5032..81da9916bc 100644
    --- a/src/MAKE/Makefile.bgl
    +++ b/src/MAKE/Makefile.bgl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.cygwin b/src/MAKE/Makefile.cygwin
    index d36456d962..b5f696bccd 100644
    --- a/src/MAKE/Makefile.cygwin
    +++ b/src/MAKE/Makefile.cygwin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.encanto b/src/MAKE/Makefile.encanto
    index e4ba3674df..f8c27278ca 100644
    --- a/src/MAKE/Makefile.encanto
    +++ b/src/MAKE/Makefile.encanto
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.fink b/src/MAKE/Makefile.fink
    index ed7c3a1d3c..b6135ba6d9 100644
    --- a/src/MAKE/Makefile.fink
    +++ b/src/MAKE/Makefile.fink
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++
    index 111495e650..584b09d85b 100755
    --- a/src/MAKE/Makefile.g++
    +++ b/src/MAKE/Makefile.g++
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++3 b/src/MAKE/Makefile.g++3
    index fc84db14c0..2cc4f16809 100755
    --- a/src/MAKE/Makefile.g++3
    +++ b/src/MAKE/Makefile.g++3
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.glory b/src/MAKE/Makefile.glory
    index eefd561817..bc282f6a0c 100644
    --- a/src/MAKE/Makefile.glory
    +++ b/src/MAKE/Makefile.glory
    @@ -110,4 +110,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.jaguar b/src/MAKE/Makefile.jaguar
    index c1e80752f4..72960e1a68 100644
    --- a/src/MAKE/Makefile.jaguar
    +++ b/src/MAKE/Makefile.jaguar
    @@ -99,4 +99,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.lam b/src/MAKE/Makefile.lam
    index b304fb04b2..cd9e4f596d 100644
    --- a/src/MAKE/Makefile.lam
    +++ b/src/MAKE/Makefile.lam
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.linux b/src/MAKE/Makefile.linux
    index 17231356d1..4d6b81a916 100755
    --- a/src/MAKE/Makefile.linux
    +++ b/src/MAKE/Makefile.linux
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac b/src/MAKE/Makefile.mac
    index 83fb667fdb..2dc11ea1f3 100755
    --- a/src/MAKE/Makefile.mac
    +++ b/src/MAKE/Makefile.mac
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac_mpi b/src/MAKE/Makefile.mac_mpi
    index 6a6afc5e0e..434b00a1e2 100755
    --- a/src/MAKE/Makefile.mac_mpi
    +++ b/src/MAKE/Makefile.mac_mpi
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mingw b/src/MAKE/Makefile.mingw
    index b88f8ef0fb..6e97ba580b 100644
    --- a/src/MAKE/Makefile.mingw
    +++ b/src/MAKE/Makefile.mingw
    @@ -101,4 +101,4 @@ mpi.o:  ../STUBS/mpi.c ../STUBS/mpi.h
     	$(CC) $(CCFLAGS) $(EXTRA_INC) -c $<
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mkl b/src/MAKE/Makefile.mkl
    index e9795da540..492f1b3a18 100644
    --- a/src/MAKE/Makefile.mkl
    +++ b/src/MAKE/Makefile.mkl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.odin b/src/MAKE/Makefile.odin
    index 4cc2f004b2..975f11511f 100755
    --- a/src/MAKE/Makefile.odin
    +++ b/src/MAKE/Makefile.odin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.openmpi b/src/MAKE/Makefile.openmpi
    index 09d15211b5..132ba0f819 100644
    --- a/src/MAKE/Makefile.openmpi
    +++ b/src/MAKE/Makefile.openmpi
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.pgi b/src/MAKE/Makefile.pgi
    index ab8cec3805..0b5167e8eb 100644
    --- a/src/MAKE/Makefile.pgi
    +++ b/src/MAKE/Makefile.pgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.power5 b/src/MAKE/Makefile.power5
    index ac736d35c6..b9cc896c82 100644
    --- a/src/MAKE/Makefile.power5
    +++ b/src/MAKE/Makefile.power5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.qed b/src/MAKE/Makefile.qed
    index 42d8b012bd..9bec6b72dc 100644
    --- a/src/MAKE/Makefile.qed
    +++ b/src/MAKE/Makefile.qed
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.redsky b/src/MAKE/Makefile.redsky
    index 6da8ac017c..de8b5ee270 100644
    --- a/src/MAKE/Makefile.redsky
    +++ b/src/MAKE/Makefile.redsky
    @@ -121,4 +121,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sdsc b/src/MAKE/Makefile.sdsc
    index 5d788a8899..5b29fbbef4 100644
    --- a/src/MAKE/Makefile.sdsc
    +++ b/src/MAKE/Makefile.sdsc
    @@ -97,4 +97,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.seaborg b/src/MAKE/Makefile.seaborg
    index a3beccb302..2d0ce36e47 100644
    --- a/src/MAKE/Makefile.seaborg
    +++ b/src/MAKE/Makefile.seaborg
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
    index b6abb9c4d7..dad2e9eea8 100755
    --- a/src/MAKE/Makefile.serial
    +++ b/src/MAKE/Makefile.serial
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial_debug b/src/MAKE/Makefile.serial_debug
    index c888377c8c..00b2620bd2 100644
    --- a/src/MAKE/Makefile.serial_debug
    +++ b/src/MAKE/Makefile.serial_debug
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sgi b/src/MAKE/Makefile.sgi
    index e3b2288ad8..e375fcf882 100644
    --- a/src/MAKE/Makefile.sgi
    +++ b/src/MAKE/Makefile.sgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.solaris b/src/MAKE/Makefile.solaris
    index 0b07e8f90a..0b05e96cd0 100644
    --- a/src/MAKE/Makefile.solaris
    +++ b/src/MAKE/Makefile.solaris
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.spirit b/src/MAKE/Makefile.spirit
    index 700df11d62..fb18d23984 100644
    --- a/src/MAKE/Makefile.spirit
    +++ b/src/MAKE/Makefile.spirit
    @@ -100,4 +100,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tacc b/src/MAKE/Makefile.tacc
    index 964347f50e..3691ef6484 100644
    --- a/src/MAKE/Makefile.tacc
    +++ b/src/MAKE/Makefile.tacc
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tbird b/src/MAKE/Makefile.tbird
    index 2df081c1e9..c3c3ac8bb2 100644
    --- a/src/MAKE/Makefile.tbird
    +++ b/src/MAKE/Makefile.tbird
    @@ -111,4 +111,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tesla b/src/MAKE/Makefile.tesla
    index 514617bbfb..9e7fd90eb1 100755
    --- a/src/MAKE/Makefile.tesla
    +++ b/src/MAKE/Makefile.tesla
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tunnison b/src/MAKE/Makefile.tunnison
    index cbb07fd91b..6717db4d3c 100644
    --- a/src/MAKE/Makefile.tunnison
    +++ b/src/MAKE/Makefile.tunnison
    @@ -103,4 +103,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xe6 b/src/MAKE/Makefile.xe6
    index e1c64a9248..3826a7ade3 100644
    --- a/src/MAKE/Makefile.xe6
    +++ b/src/MAKE/Makefile.xe6
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt3 b/src/MAKE/Makefile.xt3
    index 9a17253894..af41066561 100644
    --- a/src/MAKE/Makefile.xt3
    +++ b/src/MAKE/Makefile.xt3
    @@ -94,4 +94,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt5 b/src/MAKE/Makefile.xt5
    index 53270d5af0..ffe64fe86b 100644
    --- a/src/MAKE/Makefile.xt5
    +++ b/src/MAKE/Makefile.xt5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    --include $(DEPENDS)
    +--include $(DEPENDS)
    
    From a2fc91f4a7586928f1ffe6543f836b6891b531f2 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Fri, 30 Sep 2011 17:49:57 +0000
    Subject: [PATCH 164/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7026
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     src/MAKE/Makefile.bgl          | 2 +-
     src/MAKE/Makefile.cygwin       | 2 +-
     src/MAKE/Makefile.encanto      | 2 +-
     src/MAKE/Makefile.fink         | 2 +-
     src/MAKE/Makefile.g++          | 2 +-
     src/MAKE/Makefile.g++3         | 2 +-
     src/MAKE/Makefile.glory        | 2 +-
     src/MAKE/Makefile.jaguar       | 2 +-
     src/MAKE/Makefile.lam          | 2 +-
     src/MAKE/Makefile.linux        | 2 +-
     src/MAKE/Makefile.mac          | 2 +-
     src/MAKE/Makefile.mac_mpi      | 2 +-
     src/MAKE/Makefile.mingw        | 2 +-
     src/MAKE/Makefile.mkl          | 2 +-
     src/MAKE/Makefile.odin         | 2 +-
     src/MAKE/Makefile.openmpi      | 2 +-
     src/MAKE/Makefile.pgi          | 2 +-
     src/MAKE/Makefile.power5       | 2 +-
     src/MAKE/Makefile.qed          | 2 +-
     src/MAKE/Makefile.redsky       | 2 +-
     src/MAKE/Makefile.sdsc         | 2 +-
     src/MAKE/Makefile.seaborg      | 2 +-
     src/MAKE/Makefile.serial       | 2 +-
     src/MAKE/Makefile.serial_debug | 2 +-
     src/MAKE/Makefile.sgi          | 2 +-
     src/MAKE/Makefile.solaris      | 2 +-
     src/MAKE/Makefile.spirit       | 2 +-
     src/MAKE/Makefile.tacc         | 2 +-
     src/MAKE/Makefile.tbird        | 2 +-
     src/MAKE/Makefile.tesla        | 2 +-
     src/MAKE/Makefile.tunnison     | 2 +-
     src/MAKE/Makefile.xe6          | 2 +-
     src/MAKE/Makefile.xt3          | 2 +-
     src/MAKE/Makefile.xt5          | 2 +-
     34 files changed, 34 insertions(+), 34 deletions(-)
    
    diff --git a/src/MAKE/Makefile.bgl b/src/MAKE/Makefile.bgl
    index 81da9916bc..ad3a64d468 100644
    --- a/src/MAKE/Makefile.bgl
    +++ b/src/MAKE/Makefile.bgl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.cygwin b/src/MAKE/Makefile.cygwin
    index b5f696bccd..493ae48f66 100644
    --- a/src/MAKE/Makefile.cygwin
    +++ b/src/MAKE/Makefile.cygwin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.encanto b/src/MAKE/Makefile.encanto
    index f8c27278ca..8140f73337 100644
    --- a/src/MAKE/Makefile.encanto
    +++ b/src/MAKE/Makefile.encanto
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.fink b/src/MAKE/Makefile.fink
    index b6135ba6d9..67d81497e7 100644
    --- a/src/MAKE/Makefile.fink
    +++ b/src/MAKE/Makefile.fink
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++
    index 584b09d85b..c9480cd026 100755
    --- a/src/MAKE/Makefile.g++
    +++ b/src/MAKE/Makefile.g++
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.g++3 b/src/MAKE/Makefile.g++3
    index 2cc4f16809..490f47b7be 100755
    --- a/src/MAKE/Makefile.g++3
    +++ b/src/MAKE/Makefile.g++3
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.glory b/src/MAKE/Makefile.glory
    index bc282f6a0c..0e61e441a0 100644
    --- a/src/MAKE/Makefile.glory
    +++ b/src/MAKE/Makefile.glory
    @@ -110,4 +110,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.jaguar b/src/MAKE/Makefile.jaguar
    index 72960e1a68..0449e5348f 100644
    --- a/src/MAKE/Makefile.jaguar
    +++ b/src/MAKE/Makefile.jaguar
    @@ -99,4 +99,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.lam b/src/MAKE/Makefile.lam
    index cd9e4f596d..2c86ad752f 100644
    --- a/src/MAKE/Makefile.lam
    +++ b/src/MAKE/Makefile.lam
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.linux b/src/MAKE/Makefile.linux
    index 4d6b81a916..f0348b3eea 100755
    --- a/src/MAKE/Makefile.linux
    +++ b/src/MAKE/Makefile.linux
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac b/src/MAKE/Makefile.mac
    index 2dc11ea1f3..0742fc945a 100755
    --- a/src/MAKE/Makefile.mac
    +++ b/src/MAKE/Makefile.mac
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mac_mpi b/src/MAKE/Makefile.mac_mpi
    index 434b00a1e2..cd14f16b12 100755
    --- a/src/MAKE/Makefile.mac_mpi
    +++ b/src/MAKE/Makefile.mac_mpi
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mingw b/src/MAKE/Makefile.mingw
    index 6e97ba580b..44286bc252 100644
    --- a/src/MAKE/Makefile.mingw
    +++ b/src/MAKE/Makefile.mingw
    @@ -101,4 +101,4 @@ mpi.o:  ../STUBS/mpi.c ../STUBS/mpi.h
     	$(CC) $(CCFLAGS) $(EXTRA_INC) -c $<
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.mkl b/src/MAKE/Makefile.mkl
    index 492f1b3a18..043390f1c8 100644
    --- a/src/MAKE/Makefile.mkl
    +++ b/src/MAKE/Makefile.mkl
    @@ -98,4 +98,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.odin b/src/MAKE/Makefile.odin
    index 975f11511f..479ef95ea9 100755
    --- a/src/MAKE/Makefile.odin
    +++ b/src/MAKE/Makefile.odin
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.openmpi b/src/MAKE/Makefile.openmpi
    index 132ba0f819..ed3427a454 100644
    --- a/src/MAKE/Makefile.openmpi
    +++ b/src/MAKE/Makefile.openmpi
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.pgi b/src/MAKE/Makefile.pgi
    index 0b5167e8eb..67db1a0fe2 100644
    --- a/src/MAKE/Makefile.pgi
    +++ b/src/MAKE/Makefile.pgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.power5 b/src/MAKE/Makefile.power5
    index b9cc896c82..26d87dc92e 100644
    --- a/src/MAKE/Makefile.power5
    +++ b/src/MAKE/Makefile.power5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.qed b/src/MAKE/Makefile.qed
    index 9bec6b72dc..49349d45d2 100644
    --- a/src/MAKE/Makefile.qed
    +++ b/src/MAKE/Makefile.qed
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.redsky b/src/MAKE/Makefile.redsky
    index de8b5ee270..bc06bc8b2f 100644
    --- a/src/MAKE/Makefile.redsky
    +++ b/src/MAKE/Makefile.redsky
    @@ -121,4 +121,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sdsc b/src/MAKE/Makefile.sdsc
    index 5b29fbbef4..7ef819b34e 100644
    --- a/src/MAKE/Makefile.sdsc
    +++ b/src/MAKE/Makefile.sdsc
    @@ -97,4 +97,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.seaborg b/src/MAKE/Makefile.seaborg
    index 2d0ce36e47..e05116dcd4 100644
    --- a/src/MAKE/Makefile.seaborg
    +++ b/src/MAKE/Makefile.seaborg
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
    index dad2e9eea8..cc4480d79b 100755
    --- a/src/MAKE/Makefile.serial
    +++ b/src/MAKE/Makefile.serial
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.serial_debug b/src/MAKE/Makefile.serial_debug
    index 00b2620bd2..51f3d732d9 100644
    --- a/src/MAKE/Makefile.serial_debug
    +++ b/src/MAKE/Makefile.serial_debug
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.sgi b/src/MAKE/Makefile.sgi
    index e375fcf882..8b928717af 100644
    --- a/src/MAKE/Makefile.sgi
    +++ b/src/MAKE/Makefile.sgi
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.solaris b/src/MAKE/Makefile.solaris
    index 0b05e96cd0..bdee7ad9fc 100644
    --- a/src/MAKE/Makefile.solaris
    +++ b/src/MAKE/Makefile.solaris
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.spirit b/src/MAKE/Makefile.spirit
    index fb18d23984..0c89ed3e71 100644
    --- a/src/MAKE/Makefile.spirit
    +++ b/src/MAKE/Makefile.spirit
    @@ -100,4 +100,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tacc b/src/MAKE/Makefile.tacc
    index 3691ef6484..512c44988e 100644
    --- a/src/MAKE/Makefile.tacc
    +++ b/src/MAKE/Makefile.tacc
    @@ -95,4 +95,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tbird b/src/MAKE/Makefile.tbird
    index c3c3ac8bb2..3ee125d876 100644
    --- a/src/MAKE/Makefile.tbird
    +++ b/src/MAKE/Makefile.tbird
    @@ -111,4 +111,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tesla b/src/MAKE/Makefile.tesla
    index 9e7fd90eb1..1fa76e6b2f 100755
    --- a/src/MAKE/Makefile.tesla
    +++ b/src/MAKE/Makefile.tesla
    @@ -92,4 +92,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.tunnison b/src/MAKE/Makefile.tunnison
    index 6717db4d3c..25426113f3 100644
    --- a/src/MAKE/Makefile.tunnison
    +++ b/src/MAKE/Makefile.tunnison
    @@ -103,4 +103,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xe6 b/src/MAKE/Makefile.xe6
    index 3826a7ade3..ee2f866836 100644
    --- a/src/MAKE/Makefile.xe6
    +++ b/src/MAKE/Makefile.xe6
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt3 b/src/MAKE/Makefile.xt3
    index af41066561..f5cdc9f437 100644
    --- a/src/MAKE/Makefile.xt3
    +++ b/src/MAKE/Makefile.xt3
    @@ -94,4 +94,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    diff --git a/src/MAKE/Makefile.xt5 b/src/MAKE/Makefile.xt5
    index ffe64fe86b..f5000f0029 100644
    --- a/src/MAKE/Makefile.xt5
    +++ b/src/MAKE/Makefile.xt5
    @@ -93,4 +93,4 @@ lib:	$(OBJ)
     # Individual dependencies
     
     DEPENDS = $(OBJ:.o=.d)
    ---include $(DEPENDS)
    +sinclude $(DEPENDS)
    
    From bf962e01eed60ecf317d4411c45bec587e80b260 Mon Sep 17 00:00:00 2001
    From: sjplimp 
    Date: Tue, 4 Oct 2011 15:13:00 +0000
    Subject: [PATCH 165/246] git-svn-id:
     svn://svn.icms.temple.edu/lammps-ro/trunk@7027
     f3b2605a-c512-4ea7-a41b-209d697bcdaa
    
    ---
     doc/fix_spring.html | 11 +++++++++++
     doc/fix_spring.txt  | 11 +++++++++++
     2 files changed, 22 insertions(+)
    
    diff --git a/doc/fix_spring.html b/doc/fix_spring.html
    index 542c3f82b6..8830056177 100644
    --- a/doc/fix_spring.html
    +++ b/doc/fix_spring.html
    @@ -91,6 +91,17 @@ below the z = 0 center plane of the pore (umbrella sampling).  The
     last example holds the ion a distance 5 away from the pore axis
     (assuming the center-of-mass of the pore in x,y is the pore axis).
     

    +

    IMPORTANT NOTE: The center of mass of a group of atoms is calculated +in "unwrapped" coordinates using atom image flags, which means that +the group can straddle a periodic boundary. See the dump +doc page for a discussion of unwrapped coordinates. It also means +that a spring connecting two groups or a group and the tether point +can cross a periodic boundary and its length be calculated correctly. +One exception is for rigid bodies, which should not be used with the +fix spring command, if the rigid body will cross a periodic boundary. +This is because image flags for rigid bodies are used in a different +way, as explained on the fix rigid doc page. +

    Restart, fix_modify, output, run start/stop, minimize info:

    No information about this fix is written to binary restart diff --git a/doc/fix_spring.txt b/doc/fix_spring.txt index d3e8ee3d4f..9b65065714 100644 --- a/doc/fix_spring.txt +++ b/doc/fix_spring.txt @@ -84,6 +84,17 @@ below the z = 0 center plane of the pore (umbrella sampling). The last example holds the ion a distance 5 away from the pore axis (assuming the center-of-mass of the pore in x,y is the pore axis). +IMPORTANT NOTE: The center of mass of a group of atoms is calculated +in "unwrapped" coordinates using atom image flags, which means that +the group can straddle a periodic boundary. See the "dump"_dump.html +doc page for a discussion of unwrapped coordinates. It also means +that a spring connecting two groups or a group and the tether point +can cross a periodic boundary and its length be calculated correctly. +One exception is for rigid bodies, which should not be used with the +fix spring command, if the rigid body will cross a periodic boundary. +This is because image flags for rigid bodies are used in a different +way, as explained on the "fix rigid"_doc/fix_rigid.html doc page. + [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart From dab569f8cc70009d5ef7317bff6bab8ed85d2155 Mon Sep 17 00:00:00 2001 From: athomps Date: Wed, 5 Oct 2011 20:48:57 +0000 Subject: [PATCH 166/246] Added brackets around MAX macro. git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7028 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/neighbor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 58f8ad94dd..dda5466ed1 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1102,7 +1102,7 @@ int Neighbor::check_distance() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); - if (flagall && ago == MAX(every,delay)) ndanger++; + if (flagall && ago == (MAX(every,delay))) ndanger++; return flagall; } From d2990ef08b71f95c467f480a12bf2b7651c84185 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:15:34 +0000 Subject: [PATCH 167/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7029 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_reax_c.html | 13 ++----------- doc/pair_reax_c.txt | 15 +++------------ 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/doc/pair_reax_c.html b/doc/pair_reax_c.html index c3a81e0f98..7e5fa3ca3b 100644 --- a/doc/pair_reax_c.html +++ b/doc/pair_reax_c.html @@ -253,15 +253,6 @@ the ReaxFF potential with any LAMMPS units, but you would need to create your own potential file with coefficients listed in the appropriate units if your simulation doesn't use "real" units.

    -

    This pair style cannot yet compute per-atom energy or stress. If you -use another command that tries to calculate these quantities using -this pair style, a warning message will be printed and the quantities -will be 0.0. -

    -

    This pair style does not correctly handle interactions -involving multiple periodic images of the same atom. Hence, it should not -be used for periodic cell dimensions less than 10 angstroms. -

    Related commands:

    pair_coeff, fix_qeq_reax, @@ -280,7 +271,7 @@ Journal of Physical Chemistry A, 112, 1040-1053 (2008).

    -

    (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel -Computing, to appear (2011). +

    (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to +appear (2011).

    diff --git a/doc/pair_reax_c.txt b/doc/pair_reax_c.txt index 893ae669aa..60ef519410 100644 --- a/doc/pair_reax_c.txt +++ b/doc/pair_reax_c.txt @@ -249,15 +249,6 @@ the ReaxFF potential with any LAMMPS units, but you would need to create your own potential file with coefficients listed in the appropriate units if your simulation doesn't use "real" units. -This pair style cannot yet compute per-atom energy or stress. If you -use another command that tries to calculate these quantities using -this pair style, a warning message will be printed and the quantities -will be 0.0. - -This pair style does not correctly handle interactions -involving multiple periodic images of the same atom. Hence, it should not -be used for periodic cell dimensions less than 10 angstroms. - [Related commands:] "pair_coeff"_pair_coeff.html, "fix_qeq_reax"_fix_qeq_reax.html, @@ -273,6 +264,6 @@ The keyword default is checkqeq = yes. [(Chenoweth_2008)] Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008). -:link(Aktulga) -[(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel -Computing, to appear (2011). +:link(Aktulga) +[(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to +appear (2011). From 77371a142fc48515fd09c702b46ffbf8ac98fe46 Mon Sep 17 00:00:00 2001 From: athomps Date: Thu, 6 Oct 2011 14:25:24 +0000 Subject: [PATCH 168/246] Remove MAX parentheses again git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7030 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/neighbor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index dda5466ed1..58f8ad94dd 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1102,7 +1102,7 @@ int Neighbor::check_distance() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); - if (flagall && ago == (MAX(every,delay))) ndanger++; + if (flagall && ago == MAX(every,delay)) ndanger++; return flagall; } From 2e32772d1da9f38904ead3c70389a0d697f1a8b3 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:25:53 +0000 Subject: [PATCH 169/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7031 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-REAXC/pair_reax_c.cpp | 11 +++-- src/USER-REAXC/reaxc_allocate.cpp | 4 +- src/USER-REAXC/reaxc_basic_comm.cpp | 2 +- src/USER-REAXC/reaxc_bond_orders.cpp | 48 +++++++++++++++++- src/USER-REAXC/reaxc_bond_orders.h | 2 +- src/USER-REAXC/reaxc_bonds.cpp | 14 ++++-- src/USER-REAXC/reaxc_control.cpp | 2 +- src/USER-REAXC/reaxc_defs.h | 4 +- src/USER-REAXC/reaxc_ffield.cpp | 2 +- src/USER-REAXC/reaxc_forces.cpp | 4 +- src/USER-REAXC/reaxc_hydrogen_bonds.cpp | 25 ++++++++-- src/USER-REAXC/reaxc_init_md.cpp | 2 +- src/USER-REAXC/reaxc_io_tools.cpp | 2 +- src/USER-REAXC/reaxc_list.cpp | 2 +- src/USER-REAXC/reaxc_lookup.cpp | 2 +- src/USER-REAXC/reaxc_multi_body.cpp | 24 +++++++-- src/USER-REAXC/reaxc_nonbonded.cpp | 65 ++++++++++++++++++------- src/USER-REAXC/reaxc_reset_tools.cpp | 2 +- src/USER-REAXC/reaxc_system_props.cpp | 2 +- src/USER-REAXC/reaxc_tool_box.cpp | 2 +- src/USER-REAXC/reaxc_torsion_angles.cpp | 39 ++++++++++++++- src/USER-REAXC/reaxc_traj.cpp | 2 +- src/USER-REAXC/reaxc_types.h | 6 ++- src/USER-REAXC/reaxc_valence_angles.cpp | 32 ++++++++++-- src/USER-REAXC/reaxc_vector.cpp | 2 +- src/USER-REAXC/reaxc_vector.h | 1 + src/pair.cpp | 22 +++++++++ src/pair.h | 19 +++++--- 28 files changed, 279 insertions(+), 65 deletions(-) diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index 96bdb293e6..5828b28f34 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -86,6 +86,7 @@ PairReaxC::PairReaxC(LAMMPS *lmp) : Pair(lmp) system->bndry_cuts.ghost_bond = 0; system->bndry_cuts.ghost_cutoff = 0; system->my_atoms = NULL; + system->pair_ptr = this; fix_reax = NULL; @@ -265,7 +266,7 @@ void PairReaxC::coeff( int nargs, char **args ) void PairReaxC::init_style( ) { if (!atom->q_flag) error->all(FLERR,"Pair reax/c requires atom attribute q"); - firstwarn = 1; + // firstwarn = 1; int iqeq; for (iqeq = 0; iqeq < modify->nfix; iqeq++) @@ -395,12 +396,12 @@ void PairReaxC::compute(int eflag, int vflag) if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = eflag_global = vflag_global = 0; - if ((eflag_atom || vflag_atom) && firstwarn) { +/* if ((eflag_atom || vflag_atom) && firstwarn) { firstwarn = 0; if (comm->me == 0) error->warning(FLERR,"Pair reax/c cannot yet compute " "per-atom energy or stress"); - } + } */ if (vflag_global) control->virial = 1; else control->virial = 0; @@ -455,8 +456,8 @@ void PairReaxC::compute(int eflag, int vflag) ecoul += data->my_en.e_ele; ecoul += data->my_en.e_pol; - eng_vdwl += evdwl; - eng_coul += ecoul; + // eng_vdwl += evdwl; + // eng_coul += ecoul; // Store the different parts of the energy // in a list for output by compute pair command diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index 5a1eb6b986..37fa1207cd 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "allocate.h" #include "list.h" @@ -885,7 +885,7 @@ void ReAllocate( reax_system *system, control_params *control, if( system->numH >= DANGER_ZONE * system->Hcap || (0 && system->numH <= LOOSE_ZONE * system->Hcap) ) { Hflag = 1; - system->Hcap = MAX( system->numH * SAFER_ZONE, MIN_CAP ); + system->Hcap = int(MAX( system->numH * SAFER_ZONE, MIN_CAP )); } if( Hflag || realloc->hbonds ) { diff --git a/src/USER-REAXC/reaxc_basic_comm.cpp b/src/USER-REAXC/reaxc_basic_comm.cpp index 4be0157936..1a0452ed97 100644 --- a/src/USER-REAXC/reaxc_basic_comm.cpp +++ b/src/USER-REAXC/reaxc_basic_comm.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "basic_comm.h" #include "vector.h" diff --git a/src/USER-REAXC/reaxc_bond_orders.cpp b/src/USER-REAXC/reaxc_bond_orders.cpp index 7649181f57..a3c925f6d4 100644 --- a/src/USER-REAXC/reaxc_bond_orders.cpp +++ b/src/USER-REAXC/reaxc_bond_orders.cpp @@ -24,6 +24,7 @@ . ----------------------------------------------------------------------*/ +#include "pair_reax_c.h" #include "reaxc_types.h" #if defined(PURE_REAX) #include "bond_orders.h" @@ -544,7 +545,7 @@ void Add_dBond_to_Forces_NPT( int i, int pj, simulation_data *data, -void Add_dBond_to_Forces( int i, int pj, +void Add_dBond_to_Forces( reax_system *system, int i, int pj, storage *workspace, reax_list **lists ) { reax_list *bonds = (*lists) + BONDS; @@ -553,6 +554,10 @@ void Add_dBond_to_Forces( int i, int pj, dbond_coefficients coef; int pk, k, j; + /* Virial Tallying variables */ + int ii; + real f_scaler, fi_tmp[3], fj_tmp[3], fk_tmp[3]; + /* Initializations */ nbr_j = &(bonds->select.bond_list[pj]); j = nbr_j->nbr; @@ -589,6 +594,13 @@ void Add_dBond_to_Forces( int i, int pj, rvec_ScaledAdd( workspace->f[k], -coef.C3dbopi, nbr_k->bo_data.dBOp ); /*3rd, dBOpi2*/ rvec_ScaledAdd( workspace->f[k], -coef.C3dbopi2, nbr_k->bo_data.dBOp ); + + // tally into per-atom virial + if( system->vflag_atom ) { + f_scaler = -(coef.C2dbo + coef.C2dDelta + coef.C3dbopi + coef.C3dbopi2); + rvec_Scale( fk_tmp, -f_scaler, nbr_k->bo_data.dBOp); + system->pair_ptr->v_tally(k, fk_tmp); + } } /*1st, dBO*/ @@ -628,6 +640,13 @@ void Add_dBond_to_Forces( int i, int pj, rvec_ScaledAdd( workspace->f[k], -coef.C4dbopi, nbr_k->bo_data.dBOp ); /*4th, dBOpi2*/ rvec_ScaledAdd( workspace->f[k], -coef.C4dbopi2, nbr_k->bo_data.dBOp ); + + // tally into per-atom virial + if( system->vflag_atom ) { + f_scaler = -(coef.C3dbo + coef.C3dDelta + coef.C4dbopi + coef.C4dbopi2); + rvec_Scale( fk_tmp, -f_scaler, nbr_k->bo_data.dBOp); + system->pair_ptr->v_tally(k, fk_tmp); + } } /*1st,dBO*/ @@ -653,6 +672,33 @@ void Add_dBond_to_Forces( int i, int pj, rvec_ScaledAdd( workspace->f[j], -coef.C2dbopi2, bo_ij->dBOp ); /*3rd, dBOpi2*/ rvec_ScaledAdd( workspace->f[j], coef.C4dbopi2, workspace->dDeltap_self[j] ); + + if( system->vflag_atom) { + + // forces on i + f_scaler = coef.C1dbo + coef.C1dDelta + coef.C2dbopi + coef.C2dbopi2; + rvec_Scale( fi_tmp, -f_scaler, bo_ij->dBOp); + f_scaler = coef.C2dbo + coef.C2dDelta + coef.C3dbopi + coef.C3dbopi2; + rvec_ScaledAdd( fi_tmp, -f_scaler, workspace->dDeltap_self[i]); + f_scaler = coef.C1dbopi ; + rvec_ScaledAdd( fi_tmp, -f_scaler, bo_ij->dln_BOp_pi); + f_scaler = coef.C1dbopi2 ; + rvec_ScaledAdd( fi_tmp, -f_scaler, bo_ij->dln_BOp_pi2); + + // forces on j + f_scaler = -(coef.C1dbo + coef.C1dDelta + coef.C2dbopi + coef.C2dbopi2); + rvec_Scale( fj_tmp, -f_scaler, bo_ij->dBOp); + f_scaler = coef.C3dbo + coef.C3dDelta + coef.C4dbopi + coef.C4dbopi2; + rvec_ScaledAdd( fj_tmp, -f_scaler, workspace->dDeltap_self[j]); + f_scaler = -coef.C1dbopi ; + rvec_ScaledAdd( fj_tmp, -f_scaler, bo_ij->dln_BOp_pi); + f_scaler = -coef.C1dbopi2 ; + rvec_ScaledAdd( fj_tmp, -f_scaler, bo_ij->dln_BOp_pi2); + + system->pair_ptr->v_tally(i, fi_tmp); + system->pair_ptr->v_tally(j, fj_tmp); + + } } diff --git a/src/USER-REAXC/reaxc_bond_orders.h b/src/USER-REAXC/reaxc_bond_orders.h index cf8b1e6f00..8ca9b8b237 100644 --- a/src/USER-REAXC/reaxc_bond_orders.h +++ b/src/USER-REAXC/reaxc_bond_orders.h @@ -53,7 +53,7 @@ void Add_dDelta( reax_system*, reax_list**, int, real, rvec* ); void Add_dDelta_to_Forces( reax_system *, reax_list**, int, real ); #endif -void Add_dBond_to_Forces( int, int, storage*, reax_list** ); +void Add_dBond_to_Forces( reax_system*, int, int, storage*, reax_list** ); void Add_dBond_to_Forces_NPT( int, int, simulation_data*, storage*, reax_list** ); int BOp(storage*, reax_list*, real, int, int, far_neighbor_data*, diff --git a/src/USER-REAXC/reaxc_bonds.cpp b/src/USER-REAXC/reaxc_bonds.cpp index 6c83d41105..1617bc2735 100644 --- a/src/USER-REAXC/reaxc_bonds.cpp +++ b/src/USER-REAXC/reaxc_bonds.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "bonds.h" #include "bond_orders.h" @@ -79,7 +79,7 @@ void Bonds( reax_system *system, control_params *control, sbp_j = &( system->reax_param.sbp[type_j] ); twbp = &( system->reax_param.tbp[type_i][type_j] ); bo_ij = &( bonds->select.bond_list[pj].bo_data ); - + /* calculate the constants */ pow_BOs_be2 = pow( bo_ij->BO_s, twbp->p_be2 ); exp_be12 = exp( twbp->p_be1 * ( 1.0 - pow_BOs_be2 ) ); @@ -91,7 +91,11 @@ void Bonds( reax_system *system, control_params *control, -twbp->De_s * bo_ij->BO_s * exp_be12 -twbp->De_p * bo_ij->BO_pi -twbp->De_pp * bo_ij->BO_pi2; - + + /* tally into per-atom energy */ + if( system->evflag) + system->pair_ptr->ev_tally(i,j,natoms,1,ebond,0.0,0.0,0.0,0.0,0.0); + /* calculate derivatives of Bond Orders */ bo_ij->Cdbo += CEbo; bo_ij->Cdbopi -= (CEbo + twbp->De_p); @@ -131,6 +135,10 @@ void Bonds( reax_system *system, control_params *control, decobdboub = -gp10 * exphu * hulpov * (gp3*exphub1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); + /* tally into per-atom energy */ + if( system->evflag) + system->pair_ptr->ev_tally(i,j,natoms,1,estriph,0.0,0.0,0.0,0.0,0.0); + bo_ij->Cdbo += decobdbo; workspace->CdDelta[i] += decobdboua; workspace->CdDelta[j] += decobdboub; diff --git a/src/USER-REAXC/reaxc_control.cpp b/src/USER-REAXC/reaxc_control.cpp index 8773f7f059..4d6ccede4f 100644 --- a/src/USER-REAXC/reaxc_control.cpp +++ b/src/USER-REAXC/reaxc_control.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "control.h" #include "tool_box.h" diff --git a/src/USER-REAXC/reaxc_defs.h b/src/USER-REAXC/reaxc_defs.h index 52fc5487e3..66754291fb 100644 --- a/src/USER-REAXC/reaxc_defs.h +++ b/src/USER-REAXC/reaxc_defs.h @@ -40,8 +40,8 @@ #define CUBE(x) ((x)*(x)*(x)) #define DEG2RAD(a) ((a)*constPI/180.0) #define RAD2DEG(a) ((a)*180.0/constPI) -#define MAX(x,y) (((x) > (y)) ? (x) : (y)) -#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +// #define MAX(x,y) (((x) > (y)) ? (x) : (y)) +// #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX3(x,y,z) MAX( MAX(x,y), z) #define constPI 3.14159265 diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index 3dc310b841..546bf138d0 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "ffield.h" #include "tool_box.h" diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index 82ccebd61f..fa20fba109 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "forces.h" #include "bond_orders.h" @@ -152,7 +152,7 @@ void Compute_Total_Force( reax_system *system, control_params *control, for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) if( i < bonds->select.bond_list[pj].nbr ) { if( control->virial == 0 ) - Add_dBond_to_Forces( i, pj, workspace, lists ); + Add_dBond_to_Forces( system, i, pj, workspace, lists ); else Add_dBond_to_Forces_NPT( i, pj, data, workspace, lists ); } diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp index 14e65ba225..dc8f7dac20 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "hydrogen_bonds.h" #include "bond_orders.h" @@ -64,6 +64,9 @@ void Hydrogen_Bonds( reax_system *system, control_params *control, bond_data *bond_list; hbond_data *hbond_list; + // tally variables + real fi_tmp[3], fk_tmp[3], delij[3], delkj[3]; + bonds = (*lists) + BONDS; bond_list = bonds->select.bond_list; hbonds = (*lists) + HBONDS; @@ -134,14 +137,16 @@ void Hydrogen_Bonds( reax_system *system, control_params *control, exp_hb2 = exp( -hbp->p_hb2 * bo_ij->BO ); exp_hb3 = exp( -hbp->p_hb3 * ( hbp->r0_hb / r_jk + r_jk / hbp->r0_hb - 2.0 ) ); - + data->my_en.e_hb += e_hb = hbp->p_hb1 * (1.0 - exp_hb2) * exp_hb3 * sin_xhz4; - + CEhb1 = hbp->p_hb1 * hbp->p_hb2 * exp_hb2 * exp_hb3 * sin_xhz4; CEhb2 = -hbp->p_hb1/2.0 * (1.0 - exp_hb2) * exp_hb3 * cos_xhz1; CEhb3 = -hbp->p_hb3 * (-hbp->r0_hb / SQR(r_jk) + 1.0 / hbp->r0_hb) * e_hb; + + fprintf(stderr," H bond called \n"); /*fprintf( stdout, "%6d%6d%6d%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f\n", @@ -186,6 +191,20 @@ void Hydrogen_Bonds( reax_system *system, control_params *control, rvec_ScaledAdd( data->my_ext_press, 1.0, ext_press ); } + /* tally into per-atom virials */ + if (system->vflag_atom || system->evflag) { + rvec_ScaledSum( delij, 1., system->my_atoms[i].x, + -1., system->my_atoms[j].x ); + rvec_ScaledSum( delkj, 1., system->my_atoms[k].x, + -1., system->my_atoms[j].x ); + + rvec_Scale(fi_tmp, CEhb2, dcos_theta_di); + rvec_Scale(fk_tmp, CEhb2, dcos_theta_dk); + rvec_ScaledAdd(fk_tmp, CEhb3/r_jk, dvec_jk); + + system->pair_ptr->ev_tally3(i,j,k,e_hb,0.0,fi_tmp,fk_tmp,delij,delkj); + } + #ifdef TEST_ENERGY /* fprintf( out_control->ehb, "%24.15e%24.15e%24.15e\n%24.15e%24.15e%24.15e\n%24.15e%24.15e%24.15e\n", diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index a2d828cd9c..55d0f14348 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "init_md.h" #include "allocate.h" diff --git a/src/USER-REAXC/reaxc_io_tools.cpp b/src/USER-REAXC/reaxc_io_tools.cpp index de8830678a..960c6f5938 100644 --- a/src/USER-REAXC/reaxc_io_tools.cpp +++ b/src/USER-REAXC/reaxc_io_tools.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "io_tools.h" #include "basic_comm.h" diff --git a/src/USER-REAXC/reaxc_list.cpp b/src/USER-REAXC/reaxc_list.cpp index 8e77fe185e..6eab487af0 100644 --- a/src/USER-REAXC/reaxc_list.cpp +++ b/src/USER-REAXC/reaxc_list.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "list.h" #include "tool_box.h" diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index 0c42204610..ee54e57c55 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "lookup.h" #include "nonbonded.h" diff --git a/src/USER-REAXC/reaxc_multi_body.cpp b/src/USER-REAXC/reaxc_multi_body.cpp index f53b4709c1..fa2e719341 100644 --- a/src/USER-REAXC/reaxc_multi_body.cpp +++ b/src/USER-REAXC/reaxc_multi_body.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "multi_body.h" #include "bond_orders.h" @@ -53,6 +53,7 @@ void Atom_Energy( reax_system *system, control_params *control, real e_un, CEunder1, CEunder2, CEunder3, CEunder4; real p_lp1, p_lp2, p_lp3; real p_ovun2, p_ovun3, p_ovun4, p_ovun5, p_ovun6, p_ovun7, p_ovun8; + real eng_tmp, f_tmp; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; @@ -82,13 +83,17 @@ void Atom_Energy( reax_system *system, control_params *control, /* calculate the energy */ data->my_en.e_lp += e_lp = p_lp2 * workspace->Delta_lp[i] * inv_expvd2; - + dElp = p_lp2 * inv_expvd2 + 75 * p_lp2 * workspace->Delta_lp[i] * expvd2 * SQR(inv_expvd2); CElp = dElp * workspace->dDelta_lp[i]; workspace->CdDelta[i] += CElp; // lp - 1st term + /* tally into per-atom energy */ + if( system->evflag) + system->pair_ptr->ev_tally(i,i,system->n,1,e_lp,0.0,0.0,0.0,0.0,0.0); + #ifdef TEST_ENERGY // fprintf( out_control->elp, "%24.15e%24.15e%24.15e%24.15e\n", // p_lp2, workspace->Delta_lp_temp[i], expvd2, dElp ); @@ -115,12 +120,17 @@ void Atom_Energy( reax_system *system, control_params *control, if( vov3 > 3. ) { data->my_en.e_lp += e_lph = p_lp3 * SQR(vov3-3.0); - + deahu2dbo = 2.*p_lp3*(vov3 - 3.); deahu2dsbo = 2.*p_lp3*(vov3 - 3.)*(-1. - 0.16*pow(Di, 3.)); bo_ij->Cdbo += deahu2dbo; workspace->CdDelta[i] += deahu2dsbo; + + /* tally into per-atom energy */ + if( system->evflag) + system->pair_ptr->ev_tally(i,j,system->n,1,e_lph,0.0,0.0,0.0,0.0,0.0); + #ifdef TEST_ENERGY fprintf(out_control->elp,"C2cor%6d%6d%12.6f%12.6f%12.6f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, @@ -207,7 +217,13 @@ void Atom_Energy( reax_system *system, control_params *control, CEunder3 = CEunder1 * (1.0 - dfvl*workspace->dDelta_lp[i]*inv_exp_ovun1); CEunder4 = CEunder1 * (dfvl*workspace->Delta_lp_temp[i]) * p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1) + CEunder2; - + + /* tally into per-atom energy */ + if( system->evflag) { + eng_tmp = e_ov + e_un; + f_tmp = CEover3 + CEunder3; + system->pair_ptr->ev_tally(i,i,system->n,1,eng_tmp,0.0,0.0,0.0,0.0,0.0); + } /* forces */ workspace->CdDelta[i] += CEover3; // OvCoor - 2nd term diff --git a/src/USER-REAXC/reaxc_nonbonded.cpp b/src/USER-REAXC/reaxc_nonbonded.cpp index eabbc16d76..9b6c8f0320 100644 --- a/src/USER-REAXC/reaxc_nonbonded.cpp +++ b/src/USER-REAXC/reaxc_nonbonded.cpp @@ -24,6 +24,7 @@ . ----------------------------------------------------------------------*/ +#include "pair_reax_c.h" #include "reaxc_types.h" #if defined(PURE_REAX) #include "nonbonded.h" @@ -37,7 +38,6 @@ #include "reaxc_vector.h" #endif - void vdW_Coulomb_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) @@ -56,6 +56,9 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, reax_list *far_nbrs; // rtensor temp_rtensor, total_rtensor; + // Tallying variables: + real pe_vdw, f_tmp, delij[3]; + natoms = system->n; far_nbrs = (*lists) + FAR_NBRS; p_vdW1 = system->reax_param.gp.l[28]; @@ -93,6 +96,7 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, if (flag) { #endif + r_ij = nbr_pj->d; twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [ system->my_atoms[j].type ]); @@ -161,13 +165,23 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, data->my_en.e_ele += e_ele = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * tmp; - CEclmb = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; - // fprintf( fout, "%5d %5d %10.6f %10.6f\n", - // MIN( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), - // MAX( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), - // CEvd, CEclmb ); + + /* tally into per-atom energy */ + if( system->evflag || system->vflag_atom) { + pe_vdw = Tap * (e_vdW + e_core); + rvec_ScaledSum( delij, 1., system->my_atoms[i].x, + -1., system->my_atoms[j].x ); + f_tmp = -(CEvd + CEclmb); + system->pair_ptr->ev_tally(i,j,natoms,1,pe_vdw,e_ele, + f_tmp,delij[0],delij[1],delij[2]); + } + + /* fprintf(stderr, "%5d %5d %10.6f %10.6f\n", + MIN( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), + MAX( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), + CEvd, CEclmb ); */ if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); @@ -184,13 +198,13 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); - // fprintf( stderr, "nonbonded(%d,%d): rel_box (%f %f %f) - // force(%f %f %f) ext_press (%12.6f %12.6f %12.6f)\n", - // i, j, nbr_pj->rel_box[0], nbr_pj->rel_box[1], nbr_pj->rel_box[2], - // temp[0], temp[1], temp[2], - // data->ext_press[0], data->ext_press[1], data->ext_press[2] ); + /* fprintf( stderr, "nonbonded(%d,%d): rel_box (%f %f %f) + force(%f %f %f) ext_press (%12.6f %12.6f %12.6f)\n", + i, j, nbr_pj->rel_box[0], nbr_pj->rel_box[1], nbr_pj->rel_box[2], + temp[0], temp[1], temp[2], + data->ext_press[0], data->ext_press[1], data->ext_press[2] ); */ } - + #ifdef TEST_ENERGY // fprintf( out_control->evdw, // "%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f\n", @@ -239,6 +253,8 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, real r_ij, base, dif; real e_vdW, e_ele; real CEvd, CEclmb, SMALL = 0.0001; + real f_tmp, delij[3]; + rvec temp, ext_press; far_neighbor_data *nbr_pj; reax_list *far_nbrs; @@ -283,6 +299,7 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, #endif j = nbr_pj->nbr; type_j = system->my_atoms[j].type; + r_ij = nbr_pj->d; tmin = MIN( type_i, type_j ); tmax = MAX( type_i, type_j ); @@ -314,7 +331,17 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, CEclmb = ((t->CEclmb[r].d*dif+t->CEclmb[r].c)*dif+t->CEclmb[r].b)*dif + t->CEclmb[r].a; CEclmb *= system->my_atoms[i].q * system->my_atoms[j].q; - + + + /* tally into per-atom energy */ + if( system->evflag || system->vflag_atom) { + rvec_ScaledSum( delij, 1., system->my_atoms[i].x, + -1., system->my_atoms[j].x ); + f_tmp = -(CEvd + CEclmb); + system->pair_ptr->ev_tally(i,j,natoms,1,e_vdW,e_ele, + f_tmp,delij[0],delij[1],delij[2]); + } + if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[j], +(CEvd + CEclmb), nbr_pj->dvec ); @@ -360,16 +387,20 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, void Compute_Polarization_Energy( reax_system *system, simulation_data *data ) { int i, type_i; - real q; + real q, en_tmp; data->my_en.e_pol = 0.0; for( i = 0; i < system->n; i++ ) { q = system->my_atoms[i].q; type_i = system->my_atoms[i].type; - data->my_en.e_pol += - KCALpMOL_to_EV * (system->reax_param.sbp[type_i].chi * q + - (system->reax_param.sbp[type_i].eta / 2.) * SQR(q)); + en_tmp = KCALpMOL_to_EV * (system->reax_param.sbp[type_i].chi * q + + (system->reax_param.sbp[type_i].eta / 2.) * SQR(q)); + data->my_en.e_pol += en_tmp; + + /* tally into per-atom energy */ + if( system->evflag) + system->pair_ptr->ev_tally(i,i,system->n,1,0.0,en_tmp,0.0,0.0,0.0,0.0); } } diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index cc74118fcb..234104c190 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "reset_tools.h" #include "list.h" diff --git a/src/USER-REAXC/reaxc_system_props.cpp b/src/USER-REAXC/reaxc_system_props.cpp index 81bee6c9d7..f708d9cac3 100644 --- a/src/USER-REAXC/reaxc_system_props.cpp +++ b/src/USER-REAXC/reaxc_system_props.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "system_props.h" #include "tool_box.h" diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index a27b5030d4..1846500e05 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "tool_box.h" #elif defined(LAMMPS_REAX) diff --git a/src/USER-REAXC/reaxc_torsion_angles.cpp b/src/USER-REAXC/reaxc_torsion_angles.cpp index 33b1c5568f..940f56757b 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.cpp +++ b/src/USER-REAXC/reaxc_torsion_angles.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "torsion_angles.h" #include "bond_orders.h" @@ -201,6 +201,10 @@ void Torsion_Angles( reax_system *system, control_params *control, // char fname[100]; // FILE *ftor; + // Virial tallying variables + real delil[3], deljl[3], delkl[3]; + real eng_tmp, f_scaler, fi_tmp[3], fj_tmp[3], fk_tmp[3]; + // sprintf( fname, "tor%d.out", system->my_rank ); // ftor = fopen( fname, "w" ); @@ -479,6 +483,39 @@ void Torsion_Angles( reax_system *system, control_params *control, rvec_Add( data->my_ext_press, ext_press ); } + /* tally into per-atom virials */ + if( system->vflag_atom || system->evflag) { + + // acquire vectors + rvec_ScaledSum( delil, 1., system->my_atoms[l].x, + -1., system->my_atoms[i].x ); + rvec_ScaledSum( deljl, 1., system->my_atoms[l].x, + -1., system->my_atoms[j].x ); + rvec_ScaledSum( delkl, 1., system->my_atoms[l].x, + -1., system->my_atoms[k].x ); + // dcos_theta_ijk + rvec_Scale( fi_tmp, CEtors7 + CEconj4, p_ijk->dcos_dk ); + rvec_Scale( fj_tmp, CEtors7 + CEconj4, p_ijk->dcos_dj ); + rvec_Scale( fk_tmp, CEtors7 + CEconj4, p_ijk->dcos_di ); + + // dcos_theta_jkl + rvec_ScaledAdd( fj_tmp, CEtors8 + CEconj5, p_jkl->dcos_di ); + rvec_ScaledAdd( fk_tmp, CEtors8 + CEconj5, p_jkl->dcos_dj ); + + // dcos_omega + rvec_ScaledAdd( fi_tmp, CEtors9 + CEconj6, dcos_omega_di ); + rvec_ScaledAdd( fj_tmp, CEtors9 + CEconj6, dcos_omega_dj ); + rvec_ScaledAdd( fk_tmp, CEtors9 + CEconj6, dcos_omega_dk ); + + // tally + eng_tmp = e_tor + e_con; + if( system->evflag) + system->pair_ptr->ev_tally(j,k,natoms,1,eng_tmp,0.0,0.0,0.0,0.0,0.0); + if( system->vflag_atom) + system->pair_ptr->v_tally4(i,j,k,l,fi_tmp,fj_tmp,fk_tmp,delil,deljl,delkl); + } + + #ifdef TEST_ENERGY /* fprintf( out_control->etor, "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index 89f178b3ad..60c87a46a2 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "traj.h" #include "list.h" diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h index b288ceff3f..365b289ac0 100644 --- a/src/USER-REAXC/reaxc_types.h +++ b/src/USER-REAXC/reaxc_types.h @@ -456,7 +456,7 @@ typedef struct real ghost_cutoff; } boundary_cutoff; - +using LAMMPS_NS::Pair; typedef struct { @@ -474,6 +474,10 @@ typedef struct boundary_cutoff bndry_cuts; reax_atom *my_atoms; + + int evflag; + int vflag_atom; + class Pair *pair_ptr; } reax_system; diff --git a/src/USER-REAXC/reaxc_valence_angles.cpp b/src/USER-REAXC/reaxc_valence_angles.cpp index c2ee9408c4..8a0dd815d5 100644 --- a/src/USER-REAXC/reaxc_valence_angles.cpp +++ b/src/USER-REAXC/reaxc_valence_angles.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "valence_angles.h" #include "bond_orders.h" @@ -106,6 +106,10 @@ void Valence_Angles( reax_system *system, control_params *control, rvec force, ext_press; // rtensor temp_rtensor, total_rtensor; + // Tallying variables + real eng_tmp, f_scaler, fi_tmp[3], fj_tmp[3], fk_tmp[3]; + real delij[3], delkj[3]; + three_body_header *thbh; three_body_parameters *thbp; three_body_interaction_data *p_ijk, *p_kji; @@ -114,7 +118,6 @@ void Valence_Angles( reax_system *system, control_params *control, reax_list *bonds = (*lists) + BONDS; reax_list *thb_intrs = (*lists) + THREE_BODIES; - /* global parameters used in these calculations */ p_val6 = system->reax_param.gp.l[14]; p_val8 = system->reax_param.gp.l[33]; @@ -123,7 +126,7 @@ void Valence_Angles( reax_system *system, control_params *control, num_thb_intrs = 0; - for( j = 0; j < system->N; ++j ) { + for( j = 0; j < system->N; ++j ) { // Ray: the first one with system->N // fprintf( out_control->eval, "j: %d\n", j ); type_j = system->my_atoms[j].type; start_j = Start_Index(j, bonds); @@ -366,6 +369,7 @@ void Valence_Angles( reax_system *system, control_params *control, CEcoa5 = -2 * p_coa3 * (workspace->total_bond_order[k]-BOA_jk) * e_coa; /* END COALITION ENERGY */ + /* FORCES */ bo_ij->Cdbo += (CEval1 + CEpen2 + (CEcoa1 - CEcoa4)); @@ -390,7 +394,6 @@ void Valence_Angles( reax_system *system, control_params *control, bo_jt->Cdbopi2 += CEval5; } - if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], CEval8, p_ijk->dcos_di ); rvec_ScaledAdd( workspace->f[j], CEval8, p_ijk->dcos_dj ); @@ -411,6 +414,27 @@ void Valence_Angles( reax_system *system, control_params *control, rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); rvec_Add( data->my_ext_press, ext_press ); } + + /* tally into per-atom virials */ + if( system->vflag_atom || system->evflag) { + + /* Acquire vectors */ + rvec_ScaledSum( delij, 1., system->my_atoms[i].x, + -1., system->my_atoms[j].x ); + rvec_ScaledSum( delkj, 1., system->my_atoms[k].x, + -1., system->my_atoms[j].x ); + + rvec_Scale( fi_tmp, -CEval8, p_ijk->dcos_di ); + rvec_Scale( fj_tmp, -CEval8, p_ijk->dcos_dj ); + rvec_Scale( fk_tmp, -CEval8, p_ijk->dcos_dk ); + + eng_tmp = e_ang + e_pen + e_coa; + + if( system->evflag) + system->pair_ptr->ev_tally(j,j,system->N,1,eng_tmp,0.0,0.0,0.0,0.0,0.0); + if( system->vflag_atom) + system->pair_ptr->v_tally3(i,j,k,fi_tmp,fk_tmp,delij,delkj); + } #ifdef TEST_ENERGY /*fprintf( out_control->eval, "%12.8f%12.8f%12.8f%12.8f\n", diff --git a/src/USER-REAXC/reaxc_vector.cpp b/src/USER-REAXC/reaxc_vector.cpp index 490af6ef61..df4a546d8d 100644 --- a/src/USER-REAXC/reaxc_vector.cpp +++ b/src/USER-REAXC/reaxc_vector.cpp @@ -24,7 +24,7 @@ . ----------------------------------------------------------------------*/ -#include "reaxc_types.h" +#include "pair_reax_c.h" #if defined(PURE_REAX) #include "vector.h" #include "random.h" diff --git a/src/USER-REAXC/reaxc_vector.h b/src/USER-REAXC/reaxc_vector.h index b3bdba4025..2d43cc057c 100644 --- a/src/USER-REAXC/reaxc_vector.h +++ b/src/USER-REAXC/reaxc_vector.h @@ -27,6 +27,7 @@ #ifndef __VECTOR_H_ #define __VECTOR_H_ +#include "pair.h" #include "reaxc_types.h" #include "reaxc_defs.h" diff --git a/src/pair.cpp b/src/pair.cpp index 9374ac003b..c839078310 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -759,6 +759,28 @@ void Pair::ev_tally_list(int n, int *list, double ecoul, double *v) } } +/* ---------------------------------------------------------------------- + tally virial into per-atom accumulators + called by REAX/C potential, newton_pair is always on + fi is magnitude of force on atom i +------------------------------------------------------------------------- */ + +void Pair::v_tally(int i, double *fi) +{ + double v[6]; + double **x = atom->x; + + v[0] = x[i][0]*fi[0]; + v[1] = x[i][1]*fi[1]; + v[2] = x[i][2]*fi[2]; + v[3] = x[i][0]*fi[1]; + v[4] = x[i][0]*fi[1]; + v[5] = x[i][1]*fi[2]; + + vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2]; + vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5]; +} + /* ---------------------------------------------------------------------- tally virial into per-atom accumulators called by AIREBO potential, newton_pair is always on diff --git a/src/pair.h b/src/pair.h index 245c90389e..bc2045e179 100644 --- a/src/pair.h +++ b/src/pair.h @@ -71,6 +71,17 @@ class Pair : protected Pointers { void init_bitmap(double, double, int, int &, int &, int &, int &); virtual void modify_params(int, char **); + // need to be public, so can be called by pair_style reaxc + + void v_tally(int, double *); + void ev_tally(int, int, int, int, double, double, double, + double, double, double); + void ev_tally3(int, int, int, double, double, + double *, double *, double *, double *); + void v_tally3(int, int, int, double *, double *, double *, double *); + void v_tally4(int, int, int, int, double *, double *, double *, + double *, double *, double *); + // general child-class methods virtual void compute(int, int) = 0; @@ -125,26 +136,20 @@ class Pair : protected Pointers { int evflag; // energy,virial settings int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; + int vflag_fdotr; int maxeatom,maxvatom; virtual void ev_setup(int, int); - void ev_tally(int, int, int, int, double, double, double, - double, double, double); void ev_tally_full(int, double, double, double, double, double, double); void ev_tally_xyz(int, int, int, int, double, double, double, double, double, double, double, double); void ev_tally_xyz_full(int, double, double, double, double, double, double, double, double); - void ev_tally3(int, int, int, double, double, - double *, double *, double *, double *); void ev_tally4(int, int, int, int, double, double *, double *, double *, double *, double *, double *); void ev_tally_list(int, int *, double, double *); void v_tally2(int, int, double, double *); - void v_tally3(int, int, int, double *, double *, double *, double *); - void v_tally4(int, int, int, int, double *, double *, double *, - double *, double *, double *); void v_tally_tensor(int, int, int, int, double, double, double, double, double, double); void virial_fdotr_compute(); From 223d56efc99497eaad76fb6c9c2a78250b3b9393 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:29:03 +0000 Subject: [PATCH 170/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7032 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 6 +++--- doc/Section_commands.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index b2e5f83217..a49f2c8814 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -437,9 +437,9 @@ package.

    These are accelerated pair styles, which can be used if LAMMPS is diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index b4aa95e4c8..2cc6daaa58 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -682,7 +682,7 @@ package"_Section_start.html#start_3. "eff/cut"_pair_eff.html, "lj/coul"_pair_lj_coul.html, "lj/sf"_pair_lj_sf.html, -"reax/c"_pair_reax_c.html +"reax/c"_pair_reax_c.html, "sph/heatconduction"_pair_heatconduction.html, "sph/idealgas"_pair_idealgas.html, "sph/lj"_pair_lj.html, From 6afceab5205053580907ba503f911a392938b41d Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:32:02 +0000 Subject: [PATCH 171/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7033 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index c571f550da..0833ddae40 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "30 Sep 2011" +#define LAMMPS_VERSION "5 Oct 2011" From a7d891fbf02c775b416c80f4dbf608f4b1a73b20 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:46:34 +0000 Subject: [PATCH 172/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7035 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/KSPACE/fft3d.cpp | 4 ++-- src/KSPACE/remap.cpp | 4 ++-- src/USER-REAXC/pair_reax_c.cpp | 11 ++++------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/KSPACE/fft3d.cpp b/src/KSPACE/fft3d.cpp index fd44a42ef2..e3dbc63b1e 100644 --- a/src/KSPACE/fft3d.cpp +++ b/src/KSPACE/fft3d.cpp @@ -30,8 +30,8 @@ #include "kissfft.h" #endif -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) /* ---------------------------------------------------------------------- Data layout for 3d FFTs: diff --git a/src/KSPACE/remap.cpp b/src/KSPACE/remap.cpp index dbf9476a80..f702cf9e9e 100644 --- a/src/KSPACE/remap.cpp +++ b/src/KSPACE/remap.cpp @@ -19,8 +19,8 @@ #include "pack.h" -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) /* ---------------------------------------------------------------------- Data layout for 3d remaps: diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index 5828b28f34..f024d78843 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -396,13 +396,6 @@ void PairReaxC::compute(int eflag, int vflag) if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = eflag_global = vflag_global = 0; -/* if ((eflag_atom || vflag_atom) && firstwarn) { - firstwarn = 0; - if (comm->me == 0) - error->warning(FLERR,"Pair reax/c cannot yet compute " - "per-atom energy or stress"); - } */ - if (vflag_global) control->virial = 1; else control->virial = 0; @@ -414,6 +407,10 @@ void PairReaxC::compute(int eflag, int vflag) system->big_box.box_norms[0] = 0; system->big_box.box_norms[1] = 0; system->big_box.box_norms[2] = 0; + + system->evflag = evflag; + system->vflag_atom = vflag_atom; + if( comm->me == 0 ) t_start = MPI_Wtime(); // setup data structures From 8f91d37efdc807b6193d230d995a40fb02635dcf Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 14:47:05 +0000 Subject: [PATCH 173/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7036 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 0833ddae40..4d760c21f6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "5 Oct 2011" +#define LAMMPS_VERSION "6 Oct 2011" From f70a2f893721b5ef4b61ffd076d3d8aa444f8181 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 17:32:51 +0000 Subject: [PATCH 174/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7038 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_accelerate.html | 123 +++++++++++++++++++++++++++-- doc/Section_accelerate.txt | 123 +++++++++++++++++++++++++++-- doc/Section_commands.html | 90 ++++++++++++++++----- doc/Section_commands.txt | 101 ++++++++++++++++++++++- doc/Section_packages.html | 16 ++++ doc/Section_packages.txt | 16 ++++ doc/Section_start.html | 12 +-- doc/Section_start.txt | 12 +-- doc/angle_hybrid.html | 30 +++++++ doc/angle_hybrid.txt | 29 +++++++ doc/bond_hybrid.html | 30 +++++++ doc/bond_hybrid.txt | 29 +++++++ doc/dihedral_charmm.html | 26 ++++++ doc/dihedral_charmm.txt | 25 ++++++ doc/dihedral_class2.html | 26 ++++++ doc/dihedral_class2.txt | 25 ++++++ doc/dihedral_cosine_shift_exp.html | 26 ++++++ doc/dihedral_cosine_shift_exp.txt | 25 ++++++ doc/dihedral_harmonic.html | 26 ++++++ doc/dihedral_harmonic.txt | 25 ++++++ doc/dihedral_helix.html | 26 ++++++ doc/dihedral_helix.txt | 25 ++++++ doc/dihedral_hybrid.html | 30 +++++++ doc/dihedral_hybrid.txt | 29 +++++++ doc/dihedral_multi_harmonic.html | 26 ++++++ doc/dihedral_multi_harmonic.txt | 25 ++++++ doc/dihedral_opls.html | 26 ++++++ doc/dihedral_opls.txt | 25 ++++++ doc/fix_gravity.html | 21 ++--- doc/fix_gravity.txt | 20 ++--- doc/fix_nve_sphere.html | 26 ++++++ doc/fix_nve_sphere.txt | 25 ++++++ doc/fix_qeq_comb.html | 26 ++++++ doc/fix_qeq_comb.txt | 25 ++++++ doc/improper_hybrid.html | 30 +++++++ doc/improper_hybrid.txt | 29 +++++++ doc/pair_adp.html | 24 ++++++ doc/pair_adp.txt | 23 ++++++ doc/pair_airebo.html | 26 ++++++ doc/pair_airebo.txt | 24 ++++++ doc/pair_born.html | 16 ++-- doc/pair_born.txt | 14 ++-- doc/pair_buck.html | 18 +++-- doc/pair_buck.txt | 15 ++-- doc/pair_buck_coul.html | 24 ++++++ doc/pair_buck_coul.txt | 23 ++++++ doc/pair_charmm.html | 18 +++-- doc/pair_charmm.txt | 15 ++-- doc/pair_class2.html | 20 +++-- doc/pair_class2.txt | 17 ++-- doc/pair_colloid.html | 24 ++++++ doc/pair_colloid.txt | 23 ++++++ doc/pair_comb.html | 24 ++++++ doc/pair_comb.txt | 23 ++++++ doc/pair_coul.html | 23 +++--- doc/pair_coul.txt | 16 ++-- doc/pair_dipole.html | 26 ++++++ doc/pair_dipole.txt | 24 ++++++ doc/pair_dpd.html | 26 ++++++ doc/pair_dpd.txt | 24 ++++++ doc/pair_eam.html | 20 +++-- doc/pair_eam.txt | 17 ++-- doc/pair_edip.html | 24 ++++++ doc/pair_edip.txt | 23 ++++++ doc/pair_eim.html | 24 ++++++ doc/pair_eim.txt | 23 ++++++ doc/pair_gauss.html | 24 ++++++ doc/pair_gauss.txt | 23 ++++++ doc/pair_gayberne.html | 14 ++-- doc/pair_gayberne.txt | 13 +-- doc/pair_gran.html | 18 +++-- doc/pair_gran.txt | 15 ++-- doc/pair_gromacs.html | 16 ++-- doc/pair_gromacs.txt | 14 ++-- doc/pair_hbond_dreiding.html | 26 ++++++ doc/pair_hbond_dreiding.txt | 24 ++++++ doc/pair_hybrid.html | 30 +++++++ doc/pair_hybrid.txt | 28 +++++++ doc/pair_lj.html | 22 ++++-- doc/pair_lj.txt | 17 ++-- doc/pair_lj96.html | 14 ++-- doc/pair_lj96.txt | 13 +-- doc/pair_lj_coul.html | 24 ++++++ doc/pair_lj_coul.txt | 23 ++++++ doc/pair_lj_cubic.html | 24 ++++++ doc/pair_lj_cubic.txt | 23 ++++++ doc/pair_lj_expand.html | 14 ++-- doc/pair_lj_expand.txt | 13 +-- doc/pair_lj_sf.html | 24 ++++++ doc/pair_lj_sf.txt | 23 ++++++ doc/pair_lj_smooth.html | 14 ++-- doc/pair_lj_smooth.txt | 13 +-- doc/pair_lubricate.html | 24 ++++++ doc/pair_lubricate.txt | 23 ++++++ doc/pair_morse.html | 14 ++-- doc/pair_morse.txt | 13 +-- doc/pair_peri.html | 26 ++++++ doc/pair_peri.txt | 24 ++++++ doc/pair_resquared.html | 14 ++-- doc/pair_resquared.txt | 13 +-- doc/pair_soft.html | 24 ++++++ doc/pair_soft.txt | 23 ++++++ doc/pair_sw.html | 24 ++++++ doc/pair_sw.txt | 23 ++++++ doc/pair_table.html | 24 ++++++ doc/pair_table.txt | 23 ++++++ doc/pair_tersoff.html | 24 ++++++ doc/pair_tersoff.txt | 23 ++++++ doc/pair_tersoff_zbl.html | 24 ++++++ doc/pair_tersoff_zbl.txt | 23 ++++++ doc/pair_yukawa.html | 24 ++++++ doc/pair_yukawa.txt | 23 ++++++ doc/pair_yukawa_colloid.html | 24 ++++++ doc/pair_yukawa_colloid.txt | 23 ++++++ doc/suffix.html | 16 ++-- doc/suffix.txt | 16 ++-- 116 files changed, 2626 insertions(+), 262 deletions(-) diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html index 5c5d52ec86..79df7ef875 100644 --- a/doc/Section_accelerate.html +++ b/doc/Section_accelerate.html @@ -47,10 +47,11 @@ input script. speed-up the pairwise calculations of your simulation by 5-25%.

    Styles with an "omp" suffix are part of the USER-OMP package and allow -a pair-style to be run in threaded mode using OpenMP. This can be -useful on nodes with high-core counts when using less MPI processes +a pair-style to be run in multi-threaded mode using OpenMP. This can +be useful on nodes with high-core counts when using less MPI processes than cores is advantageous, e.g. when running with PPPM so that FFTs -are run on fewer MPI processors. +are run on fewer MPI processors or when the many MPI tasks would +overload the available bandwidth for communication.

    Styles with a "gpu" or "cuda" suffix are part of the GPU or USER-CUDA packages, and can be run on NVIDIA GPUs associated with your CPUs. @@ -114,8 +115,120 @@ to 20% savings.

    5.2 USER-OMP package

    -

    This section will be written when the USER-OMP package is released -in main LAMMPS. +

    The USER-OMP package was developed by Axel Kohlmeyer at Temple University. +It provides multi-threaded versions of most pair styles, all dihedral +styles and a few fixes in LAMMPS. The package currently uses the OpenMP +interface which requires using a specific compiler flag in the makefile +to enable multiple threads; without this flag the corresponding pair +styles will still be compiled and work, but do not support multi-threading. +

    +

    Building LAMMPS with the USER-OMP package: +

    +

    The procedure for building LAMMPS with the USER-OMP package is simple. +You have to edit your machine specific makefile to add the flag to +enable OpenMP support to the CCFLAGS and LINKFLAGS variables. For the +GNU compilers for example this flag is called -fopenmp. Check your +compiler documentation to find out which flag you need to add. +The rest of the compilation is the same as for any other package which +has no additional library dependencies: +

    +
    make yes-user-omp
    +make machine 
    +
    +

    Please note that this will only install accelerated versions +of styles that are already installed, so you want to install +this package as the last package, or else you may be missing +some accelerated styles. If you plan to uninstall some package, +you should first uninstall the USER-OMP package then the other +package and then re-install USER-OMP, to make sure that there +are no orphaned omp style files present, which would lead to +compilation errors. +

    +

    If your input script uses one of regular styles that are also +exist as an OpenMP version in the USER-OMP package you can run +it as follows: +

    +
    env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script
    +env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script
    +mpirun -x OMP_NUM_THRADS=2 -np 2 lmp_machine -sf omp -in in.script 
    +
    +

    The value of the environment variable OMP_NUM_THREADS determines how +many threads per MPI task are launched. All three examples above use +a total of 4 CPU cores. For different MPI implementations the method +to pass the OMP_NUM_THREADS environment variable to all processes is +different. Two different variants, one for MPICH and OpenMPI, respectively +are shown above. Please check the documentation of your MPI installation +for additional details. Alternatively, the value provided by OMP_NUM_THREADS +can be overridded with the package omp command. +Depending on which styles are accelerated in your input, you should +see a reduction in the "Pair time" and/or "Bond time" and "Loop time" +printed out at the end of the run. The optimal ratio of MPI to OpenMP +can vary a lot and should always be confirmed through some benchmark +runs for the current system and on the current machine. +

    +

    Restrictions: +

    +

    None of the pair styles in the USER-OMP package support the "inner", +"middle", "outer" options for r-RESPA integration, only the "pair" +option is supported. +

    +

    Parallel efficiency and performance tips: +

    +

    In most simple cases the MPI parallelization in LAMMPS is more +efficient than multi-threading implemented in the USER-OMP package. +Also the parallel efficiency varies between individual styles. +On the other hand, in many cases you still want to use the omp version +- even when compiling or running without OpenMP support - since they +all contain optimizations similar to those in the OPT package, which +can result in serial speedup. +

    +

    Using multi-threading is most effective under the following circumstances: +

    +
    • Individual compute nodes have a significant number of CPU cores +but the CPU itself has limited memory bandwidth, e.g. Intel Xeon 53xx +(Clovertown) and 54xx (Harpertown) quad core processors. Running +one MPI task per CPU core will result in significant performance +degradation, so that running with 4 or even only 2 MPI tasks per +nodes is faster. Running in hybrid MPI+OpenMP mode will reduce the +inter-node communication bandwidth contention in the same way, +but offers and additional speedup from utilizing the otherwise +idle CPU cores. + +
    • The interconnect used for MPI communication is not able to provide +sufficient bandwidth for a large number of MPI tasks per node. +This applies for example to running over gigabit ethernet or +on Cray XT4 or XT5 series supercomputers. Same as in the aforementioned +case this effect worsens with using an increasing number of nodes. + +
    • The input is a system that has an inhomogeneous particle density +which cannot be mapped well to the domain decomposition scheme +that LAMMPS employs. While this can be to some degree alleviated +through using the processors keyword, multi-threading +provides a parallelism that parallelizes over the number of particles +not their distribution in space. + +
    • Finally, multi-threaded styles can improve performance when running +LAMMPS in "capability mode", i.e. near the point where the MPI +parallelism scales out. This can happen in particular when using +as kspace style for long-range electrostatics. Here the scaling +of the kspace style is the performance limiting factor and using +multi-threaded styles allows to operate the kspace style at the +limit of scaling and then increase performance parallelizing +the real space calculations with hybrid MPI+OpenMP. Sometimes +additional speedup can be achived by increasing the real-space +coulomb cutoff and thus reducing the work in the kspace part. +
    +

    The best parallel efficiency from omp styles is typically +achieved when there is at least one MPI task per physical +processor, i.e. socket or die. +

    +

    Using threads on hyper-threading enabled cores is usually +counterproductive, as the cost in additional memory bandwidth +requirements is not offset by the gain in CPU utilization +through hyper-threading. +

    +

    A description of the multi-threading strategy and some performance +examples are presented here


    diff --git a/doc/Section_accelerate.txt b/doc/Section_accelerate.txt index e98f7c85ea..fc06f3bcd4 100644 --- a/doc/Section_accelerate.txt +++ b/doc/Section_accelerate.txt @@ -44,10 +44,11 @@ Styles with an "opt" suffix are part of the OPT package and typically speed-up the pairwise calculations of your simulation by 5-25%. Styles with an "omp" suffix are part of the USER-OMP package and allow -a pair-style to be run in threaded mode using OpenMP. This can be -useful on nodes with high-core counts when using less MPI processes +a pair-style to be run in multi-threaded mode using OpenMP. This can +be useful on nodes with high-core counts when using less MPI processes than cores is advantageous, e.g. when running with PPPM so that FFTs -are run on fewer MPI processors. +are run on fewer MPI processors or when the many MPI tasks would +overload the available bandwidth for communication. Styles with a "gpu" or "cuda" suffix are part of the GPU or USER-CUDA packages, and can be run on NVIDIA GPUs associated with your CPUs. @@ -109,8 +110,120 @@ to 20% savings. 5.2 USER-OMP package :h4,link(acc_2) -This section will be written when the USER-OMP package is released -in main LAMMPS. +The USER-OMP package was developed by Axel Kohlmeyer at Temple University. +It provides multi-threaded versions of most pair styles, all dihedral +styles and a few fixes in LAMMPS. The package currently uses the OpenMP +interface which requires using a specific compiler flag in the makefile +to enable multiple threads; without this flag the corresponding pair +styles will still be compiled and work, but do not support multi-threading. + +[Building LAMMPS with the USER-OMP package:] + +The procedure for building LAMMPS with the USER-OMP package is simple. +You have to edit your machine specific makefile to add the flag to +enable OpenMP support to the CCFLAGS and LINKFLAGS variables. For the +GNU compilers for example this flag is called {-fopenmp}. Check your +compiler documentation to find out which flag you need to add. +The rest of the compilation is the same as for any other package which +has no additional library dependencies: + +make yes-user-omp +make machine :pre + +Please note that this will only install accelerated versions +of styles that are already installed, so you want to install +this package as the last package, or else you may be missing +some accelerated styles. If you plan to uninstall some package, +you should first uninstall the USER-OMP package then the other +package and then re-install USER-OMP, to make sure that there +are no orphaned {omp} style files present, which would lead to +compilation errors. + +If your input script uses one of regular styles that are also +exist as an OpenMP version in the USER-OMP package you can run +it as follows: + +env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script +env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script +mpirun -x OMP_NUM_THRADS=2 -np 2 lmp_machine -sf omp -in in.script :pre + +The value of the environment variable OMP_NUM_THREADS determines how +many threads per MPI task are launched. All three examples above use +a total of 4 CPU cores. For different MPI implementations the method +to pass the OMP_NUM_THREADS environment variable to all processes is +different. Two different variants, one for MPICH and OpenMPI, respectively +are shown above. Please check the documentation of your MPI installation +for additional details. Alternatively, the value provided by OMP_NUM_THREADS +can be overridded with the "package omp"_package.html command. +Depending on which styles are accelerated in your input, you should +see a reduction in the "Pair time" and/or "Bond time" and "Loop time" +printed out at the end of the run. The optimal ratio of MPI to OpenMP +can vary a lot and should always be confirmed through some benchmark +runs for the current system and on the current machine. + +[Restrictions:] + +None of the pair styles in the USER-OMP package support the "inner", +"middle", "outer" options for r-RESPA integration, only the "pair" +option is supported. + +[Parallel efficiency and performance tips:] + +In most simple cases the MPI parallelization in LAMMPS is more +efficient than multi-threading implemented in the USER-OMP package. +Also the parallel efficiency varies between individual styles. +On the other hand, in many cases you still want to use the {omp} version +- even when compiling or running without OpenMP support - since they +all contain optimizations similar to those in the OPT package, which +can result in serial speedup. + +Using multi-threading is most effective under the following circumstances: + +Individual compute nodes have a significant number of CPU cores +but the CPU itself has limited memory bandwidth, e.g. Intel Xeon 53xx +(Clovertown) and 54xx (Harpertown) quad core processors. Running +one MPI task per CPU core will result in significant performance +degradation, so that running with 4 or even only 2 MPI tasks per +nodes is faster. Running in hybrid MPI+OpenMP mode will reduce the +inter-node communication bandwidth contention in the same way, +but offers and additional speedup from utilizing the otherwise +idle CPU cores. :ulb,l + +The interconnect used for MPI communication is not able to provide +sufficient bandwidth for a large number of MPI tasks per node. +This applies for example to running over gigabit ethernet or +on Cray XT4 or XT5 series supercomputers. Same as in the aforementioned +case this effect worsens with using an increasing number of nodes. :l + +The input is a system that has an inhomogeneous particle density +which cannot be mapped well to the domain decomposition scheme +that LAMMPS employs. While this can be to some degree alleviated +through using the "processors"_processors.html keyword, multi-threading +provides a parallelism that parallelizes over the number of particles +not their distribution in space. :l + +Finally, multi-threaded styles can improve performance when running +LAMMPS in "capability mode", i.e. near the point where the MPI +parallelism scales out. This can happen in particular when using +as kspace style for long-range electrostatics. Here the scaling +of the kspace style is the performance limiting factor and using +multi-threaded styles allows to operate the kspace style at the +limit of scaling and then increase performance parallelizing +the real space calculations with hybrid MPI+OpenMP. Sometimes +additional speedup can be achived by increasing the real-space +coulomb cutoff and thus reducing the work in the kspace part. :l,ule + +The best parallel efficiency from {omp} styles is typically +achieved when there is at least one MPI task per physical +processor, i.e. socket or die. + +Using threads on hyper-threading enabled cores is usually +counterproductive, as the cost in additional memory bandwidth +requirements is not offset by the gain in CPU utilization +through hyper-threading. + +A description of the multi-threading strategy and some performance +examples are "presented here"_http://sites.google.com/site/akohlmey/software/lammps-icms/lammps-icms-tms2011-talk.pdf?attredirects=0&d=1 :line :line diff --git a/doc/Section_commands.html b/doc/Section_commands.html index a49f2c8814..92b37781ee 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -354,9 +354,9 @@ of each style or click on the style itself for a full description: package.

    These are accelerated fix styles, which can be used if LAMMPS is @@ -364,9 +364,9 @@ built with the appropriate accelerated package.


    @@ -437,9 +437,9 @@ package.

    These are accelerated pair styles, which can be used if LAMMPS is @@ -447,19 +447,34 @@ built with the appropriate accelerated package.

    - + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
    born/coul/long/cudabuck/coul/cut/cudabuck/coul/long/cudabuck/cuda
    adp/ompairebo/ompborn/coul/long/cudaborn/coul/long/omp
    born/ompbuck/coul/cut/cudabuck/coul/cut/ompbuck/coul/long/cuda
    buck/coul/long/ompbuck/coul/ompbuck/cudabuck/omp
    cg/cmm/coul/cut/cudacg/cmm/coul/debye/cudacg/cmm/coul/long/cudacg/cmm/coul/long/gpu
    cg/cmm/cudacg/cmm/gpucoul/long/gpueam/alloy/cuda
    eam/alloy/opteam/cudaeam/fs/cudaeam/fs/opt
    eam/optgayberne/gpugran/hooke/cudalj/charmm/coul/charmm/cuda
    lj/charmm/coul/charmm/implicit/cudalj/charmm/coul/long/cudalj/charmm/coul/long/gpulj/charmm/coul/long/opt
    lj/class2/coul/cut/cudalj/class2/coul/long/cudalj/class2/coul/long/gpulj/class2/cuda
    lj/class2/gpulj/cut/coul/cut/cudalj/cut/coul/cut/gpulj/cut/coul/debye/cuda
    lj/cut/coul/long/cudalj/cut/coul/long/gpulj/cut/coul/long/optlj/cut/coul/long/tip4p/opt
    lj/cut/cudalj/cut/experimental/cudalj/cut/gpulj/cut/opt
    lj/expand/cudalj/expand/gpulj/gromacs/coul/gromacs/cudalj/gromacs/cuda
    lj/smooth/cudalj96/cut/cudalj96/cut/gpumorse/cuda
    morse/gpumorse/optresquared/gpu +
    cg/cmm/cudacg/cmm/gpucolloid/ompcomb/omp
    coul/cut/ompcoul/debye/ompcoul/long/gpucoul/long/omp
    dipole/cut/ompdipole/sf/ompdpd/ompdpd/tstat/omp
    eam/alloy/cudaeam/alloy/ompeam/alloy/opteam/cd/omp
    eam/cudaeam/fs/cudaeam/fs/ompeam/fs/opt
    eam/ompeam/optedip/ompeim/omp
    gauss/ompgayberne/gpugayberne/ompgran/hertz/history/omp
    gran/hooke/cudagran/hooke/history/ompgran/hooke/omphbond/dreiding/lj/omp
    hbond/dreiding/morse/omplj/charmm/coul/charmm/cudalj/charmm/coul/charmm/omplj/charmm/coul/charmm/implicit/cuda
    lj/charmm/coul/charmm/implicit/omplj/charmm/coul/long/cudalj/charmm/coul/long/gpulj/charmm/coul/long/omp
    lj/charmm/coul/long/optlj/class2/coul/cut/cudalj/class2/coul/cut/omplj/class2/coul/long/cuda
    lj/class2/coul/long/gpulj/class2/coul/long/omplj/class2/cudalj/class2/gpu
    lj/class2/omplj/coul/omplj/cut/coul/cut/cudalj/cut/coul/cut/gpu
    lj/cut/coul/cut/omplj/cut/coul/debye/cudalj/cut/coul/debye/omplj/cut/coul/long/cuda
    lj/cut/coul/long/gpulj/cut/coul/long/omplj/cut/coul/long/optlj/cut/coul/long/tip4p/omp
    lj/cut/coul/long/tip4p/optlj/cut/cudalj/cut/experimental/cudalj/cut/gpu
    lj/cut/omplj/cut/optlj/expand/cudalj/expand/gpu
    lj/expand/omplj/gromacs/coul/gromacs/cudalj/gromacs/coul/gromacs/omplj/gromacs/cuda
    lj/gromacs/omplj/sf/omplj/smooth/cudalj/smooth/omp
    lj96/cut/cudalj96/cut/gpulj96/cut/omplubricate/omp
    morse/cudamorse/gpumorse/ompmorse/opt
    peri/lps/ompperi/pmb/omprebo/ompresquared/gpu resquared/omp
    soft/ompsw/omptable/omptersoff/omp
    tersoff/zbl/ompyukawa/ompyukawa/colloid/omp

    @@ -483,6 +498,14 @@ package. harmonic/shiftharmonic/shift/cut +

    These are accelerated bond styles, which can be used if LAMMPS is +built with the appropriate accelerated +package. +

    + +

    Angle_style potentials @@ -504,6 +527,14 @@ package. cg/cmmcosine/shiftcosine/shift/exp +

    These are accelerated angle styles, which can be used if LAMMPS is +built with the appropriate accelerated +package. +

    + +

    Dihedral_style potentials @@ -525,6 +556,15 @@ package. cosine/shift/exp +

    These are accelerated dihedral styles, which can be used if LAMMPS is +built with the appropriate accelerated +package. +

    + +

    Improper_style potentials @@ -538,6 +578,14 @@ description: harmonicumbrella +

    These are accelerated improper styles, which can be used if LAMMPS is +built with the appropriate accelerated +package. +

    + +

    Kspace solvers diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 2cc6daaa58..3fdae72257 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -485,6 +485,7 @@ These are fix styles contributed by users, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. +"addtorque"_fix_addtorque.html, "atc"_fix_atc.html, "imd"_fix_imd.html, "langevin/eff"_fix_langevin_eff.html, @@ -505,13 +506,15 @@ package"_Section_accelerate.html. "freeze/cuda"_fix_freeze.html, "addforce/cuda"_fix_addforce.html, -"addtorque"_fix_addtorque.html, "aveforce/cuda"_fix_aveforce.html, "enforce2d/cuda"_fix_enforce2d.html, "gravity/cuda"_fix_gravity.html, +"gravity/omp"_fix_gravity.html, "npt/cuda"_fix_nh.html, "nve/cuda"_fix_nh.html, +"nve/sphere/omp"_fix_nve_sphere.html, "nvt/cuda"_fix_nh.html, +"qeq/comb/omp"_fix_qeq_comb.html, "setforce/cuda"_fix_setforce.html, "shake/cuda"_fix_shake.html, "temp/berendsen/cuda"_fix_temp_berendsen.html, @@ -682,7 +685,7 @@ package"_Section_start.html#start_3. "eff/cut"_pair_eff.html, "lj/coul"_pair_lj_coul.html, "lj/sf"_pair_lj_sf.html, -"reax/c"_pair_reax_c.html, +"reax/c"_pair_reax_c.html "sph/heatconduction"_pair_heatconduction.html, "sph/idealgas"_pair_idealgas.html, "sph/lj"_pair_lj.html, @@ -694,57 +697,118 @@ These are accelerated pair styles, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. +"adp/omp"_pair_adp.html, +"airebo/omp"_pair_airebo.html, "born/coul/long/cuda"_pair_born.html, +"born/coul/long/omp"_pair_born.html, +"born/omp"_pair_born.html, "buck/coul/cut/cuda"_pair_buck.html, +"buck/coul/cut/omp"_pair_buck.html, "buck/coul/long/cuda"_pair_buck.html, +"buck/coul/long/omp"_pair_buck.html, +"buck/coul/omp"_pair_buck_coul.html, "buck/cuda"_pair_buck.html, +"buck/omp"_pair_buck.html, "cg/cmm/coul/cut/cuda"_pair_cmm.html, "cg/cmm/coul/debye/cuda"_pair_cmm.html, "cg/cmm/coul/long/cuda"_pair_cmm.html, "cg/cmm/coul/long/gpu"_pair_cmm.html, "cg/cmm/cuda"_pair_cmm.html, "cg/cmm/gpu"_pair_cmm.html, +"colloid/omp"_pair_colloid.html, +"comb/omp"_pair_comb.html, +"coul/cut/omp"_pair_coul.html, +"coul/debye/omp"_pair_coul.html, "coul/long/gpu"_pair_coul.html, +"coul/long/omp"_pair_coul.html, +"dipole/cut/omp"_pair_dipole.html, +"dipole/sf/omp"_pair_dipole.html, +"dpd/omp"_pair_dpd.html, +"dpd/tstat/omp"_pair_dpd.html, "eam/alloy/cuda"_pair_eam.html, +"eam/alloy/omp"_pair_eam.html, "eam/alloy/opt"_pair_eam.html, +"eam/cd/omp"_pair_eam.html, "eam/cuda"_pair_eam.html, "eam/fs/cuda"_pair_eam.html, +"eam/fs/omp"_pair_eam.html, "eam/fs/opt"_pair_eam.html, +"eam/omp"_pair_eam.html, "eam/opt"_pair_eam.html, +"edip/omp"_pair_edip.html, +"eim/omp"_pair_eim.html, +"gauss/omp"_pair_gauss.html, "gayberne/gpu"_pair_gayberne.html, +"gayberne/omp"_pair_gayberne.html, +"gran/hertz/history/omp"_pair_gran.html, "gran/hooke/cuda"_pair_gran.html, +"gran/hooke/history/omp"_pair_gran.html, +"gran/hooke/omp"_pair_gran.html, +"hbond/dreiding/lj/omp"_pair_hbond_dreiding.html, +"hbond/dreiding/morse/omp"_pair_hbond_dreiding.html, "lj/charmm/coul/charmm/cuda"_pair_charmm.html, +"lj/charmm/coul/charmm/omp"_pair_charmm.html, "lj/charmm/coul/charmm/implicit/cuda"_pair_charmm.html, +"lj/charmm/coul/charmm/implicit/omp"_pair_charmm.html, "lj/charmm/coul/long/cuda"_pair_charmm.html, "lj/charmm/coul/long/gpu"_pair_charmm.html, +"lj/charmm/coul/long/omp"_pair_charmm.html, "lj/charmm/coul/long/opt"_pair_charmm.html, "lj/class2/coul/cut/cuda"_pair_class2.html, +"lj/class2/coul/cut/omp"_pair_class2.html, "lj/class2/coul/long/cuda"_pair_class2.html, "lj/class2/coul/long/gpu"_pair_class2.html, +"lj/class2/coul/long/omp"_pair_class2.html, "lj/class2/cuda"_pair_class2.html, "lj/class2/gpu"_pair_class2.html, +"lj/class2/omp"_pair_class2.html, +"lj/coul/omp"_pair_lj_coul.html, "lj/cut/coul/cut/cuda"_pair_lj.html, "lj/cut/coul/cut/gpu"_pair_lj.html, +"lj/cut/coul/cut/omp"_pair_lj.html, "lj/cut/coul/debye/cuda"_pair_lj.html, +"lj/cut/coul/debye/omp"_pair_lj.html, "lj/cut/coul/long/cuda"_pair_lj.html, "lj/cut/coul/long/gpu"_pair_lj.html, +"lj/cut/coul/long/omp"_pair_lj.html, "lj/cut/coul/long/opt"_pair_lj.html, +"lj/cut/coul/long/tip4p/omp"_pair_lj.html, "lj/cut/coul/long/tip4p/opt"_pair_lj.html, "lj/cut/cuda"_pair_lj.html, "lj/cut/experimental/cuda"_pair_lj.html, "lj/cut/gpu"_pair_lj.html, +"lj/cut/omp"_pair_lj.html, "lj/cut/opt"_pair_lj.html, "lj/expand/cuda"_pair_lj_expand.html, "lj/expand/gpu"_pair_lj_expand.html, +"lj/expand/omp"_pair_lj_expand.html, "lj/gromacs/coul/gromacs/cuda"_pair_gromacs.html, +"lj/gromacs/coul/gromacs/omp"_pair_gromacs.html, "lj/gromacs/cuda"_pair_gromacs.html, +"lj/gromacs/omp"_pair_gromacs.html, +"lj/sf/omp"_pair_lj_sf.html, "lj/smooth/cuda"_pair_lj_smooth.html, +"lj/smooth/omp"_pair_lj_smooth.html, "lj96/cut/cuda"_pair_lj96.html, "lj96/cut/gpu"_pair_lj96.html, +"lj96/cut/omp"_pair_lj96.html, +"lubricate/omp"_pair_lubricate.html, "morse/cuda"_pair_morse.html, "morse/gpu"_pair_morse.html, +"morse/omp"_pair_morse.html, "morse/opt"_pair_morse.html, -"resquared/gpu"_pair_resquared.html :tb(c=4,ea=c) +"peri/lps/omp"_pair_peri.html, +"peri/pmb/omp"_pair_peri.html, +"rebo/omp"_pair_airebo.html, +"resquared/gpu"_pair_resquared.html +"resquared/omp"_pair_resquared.html, +"soft/omp"_pair_soft.html, +"sw/omp"_pair_sw.html, +"table/omp"_pair_table.html, +"tersoff/omp"_pair_tersoff.html, +"tersoff/zbl/omp"_pair_tersoff_zbl.html, +"yukawa/omp"_pair_yukawa.html, +"yukawa/colloid/omp"_pair_yukawa_colloid.html :tb(c=4,ea=c) :line @@ -771,6 +835,12 @@ package"_Section_start.html#start_3. "harmonic/shift"_bond_harmonic_shift.html, "harmonic/shift/cut"_bond_harmonic_shift_cut.html :tb(c=4,ea=c) +These are accelerated bond styles, which can be used if LAMMPS is +built with the "appropriate accelerated +package"_Section_accelerate.html. + +"hybrid/omp"_bond_hybrid.html :tb(c=4,ea=c) + :line Angle_style potentials :h4 @@ -797,6 +867,12 @@ package"_Section_start.html#start_3. "cosine/shift"_angle_cosine_shift.html, "cosine/shift/exp"_angle_cosine_shift_exp.html :tb(c=4,ea=c) +These are accelerated angle styles, which can be used if LAMMPS is +built with the "appropriate accelerated +package"_Section_accelerate.html. + +"hybrid/omp"_angle_hybrid.html :tb(c=4,ea=c) + :line Dihedral_style potentials :h4 @@ -820,6 +896,19 @@ package"_Section_start.html#start_3. "cosine/shift/exp"_dihedral_cosine_shift_exp.html :tb(c=4,ea=c) +These are accelerated dihedral styles, which can be used if LAMMPS is +built with the "appropriate accelerated +package"_Section_accelerate.html. + +"hybrid/omp"_dihedral_hybrid.html, +"charmm/omp"_dihedral_charmm.html, +"class2/omp"_dihedral_class2.html, +"cosine/shift/exp/omp"_dihedral_cosine_shift_exp.html, +"harmonic/omp"_dihedral_harmonic.html, +"helix/omp"_dihedral_helix.html, +"multi/harmonic/omp"_dihedral_multi_harmonic.html, +"opls/omp"_dihedral_opls.html :tb(c=4,ea=c,w=100) + :line Improper_style potentials :h4 @@ -835,6 +924,12 @@ description: "harmonic"_improper_harmonic.html, "umbrella"_improper_umbrella.html :tb(c=4,ea=c,w=100) +These are accelerated improper styles, which can be used if LAMMPS is +built with the "appropriate accelerated +package"_Section_accelerate.html. + +"hybrid/omp"_improper_hybrid.html :tb(c=4,ea=c,w=100) + :line Kspace solvers :h4 diff --git a/doc/Section_packages.html b/doc/Section_packages.html index 8c082f1096..64de0748ee 100644 --- a/doc/Section_packages.html +++ b/doc/Section_packages.html @@ -97,6 +97,7 @@ E.g. "peptide" refers to the examples/peptide directory. USER-CUDA NVIDIA GPU styles Christian Trott (U Tech Ilmenau) accelerate USER/cuda - lib/cuda USER-EFF electron force field Andres Jaramillo-Botero (Caltech) pair_style eff/cut USER/eff eff - USER-EWALDN Ewald for 1/R^n Pieter in' t Veld (BASF) kspace_style - - - +USER-OMP OpenMP threaded styles Axel Kohlmeyer (Temple U) accelerate - - - USER-REAXC C version of ReaxFF Metin Aktulga (LBNL) pair_style reaxc reax - - USER-SPH smoothed particle hydrodynamics Georg Ganzenmuller (EMI) SPH_LAMMPS_userguide.pdf USER/sph sph - @@ -327,6 +328,21 @@ directly if you have questions.


    +

    USER-OMP package +

    +

    This package provides OpenMP multi-threading support and +other optimizations of various LAMMPS pair styles, dihedral +styles, and fix styles. +

    +

    See this section of the manual to get started: +

    +

    Section_accelerate +

    +

    The person who created this package is Axel Kohlmeyer at Temple U +(akohlmey at gmail.com). Contact him directly if you have questions. +

    +
    +

    USER-REAXC package

    This package contains a implementation for LAMMPS of the ReaxFF force diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt index 3dfad2f11b..928820c7df 100644 --- a/doc/Section_packages.txt +++ b/doc/Section_packages.txt @@ -89,6 +89,7 @@ USER-CG-CMM, coarse-graining model, Axel Kohlmeyer (Temple U), "pair_style cg/cm USER-CUDA, NVIDIA GPU styles, Christian Trott (U Tech Ilmenau), "accelerate"_Section_accelerate.html#acc_4, USER/cuda, -, lib/cuda USER-EFF, electron force field, Andres Jaramillo-Botero (Caltech), "pair_style eff/cut"_pair_eff.html, USER/eff, "eff"_eff, - USER-EWALDN, Ewald for 1/R^n, Pieter in' t Veld (BASF), "kspace_style"_kspace_style.html, -, -, - +USER-OMP, OpenMP threaded styles, Axel Kohlmeyer (Temple U), "accelerate"_Section_accelerate.html#acc_2, -, -, - USER-REAXC, C version of ReaxFF, Metin Aktulga (LBNL), "pair_style reaxc"_pair_reax_c.html, reax, -, - USER-SPH, smoothed particle hydrodynamics, Georg Ganzenmuller (EMI), "SPH_LAMMPS_userguide.pdf"_USER/sph/SPH_LAMMPS_userguide.pdf, USER/sph, "sph"_sph, - :tb(ea=c) @@ -315,6 +316,21 @@ directly if you have questions. :line +USER-OMP package :h4 + +This package provides OpenMP multi-threading support and +other optimizations of various LAMMPS pair styles, dihedral +styles, and fix styles. + +See this section of the manual to get started: + +"Section_accelerate"_Section_accelerate.html#acc_2 + +The person who created this package is Axel Kohlmeyer at Temple U +(akohlmey at gmail.com). Contact him directly if you have questions. + +:line + USER-REAXC package :h4 This package contains a implementation for LAMMPS of the ReaxFF force diff --git a/doc/Section_start.html b/doc/Section_start.html index 976e2666e9..bfe24d404e 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -978,18 +978,18 @@ partition screen files file.N.

    -suffix style 
     

    Use variants of various styles if they exist. The specified style can -be opt or gpu or cuda. These refer to optional packages that +be opt, omp, gpu, or cuda. These refer to optional packages that LAMMPS can be built with, as described above in Section 2.3. The "opt" style corrsponds to the OPT package, the -"gpu" style to the GPU package, and the "cuda" style to the USER-CUDA -package. +"omp" style to the USER-OMP package, the "gpu" style to the GPU +package, and the "cuda" style to the USER-CUDA package.

    As an example, all of the packages provide a pair_style -lj/cut variant, with style names lj/cut/opt or -lj/cut/gpu or lj/cut/cuda. A variant styles can be specified +lj/cut variant, with style names lj/cut/opt, lj/cut/omp, +lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified explicitly in your input script, e.g. pair_style lj/cut/gpu. If the -suffix switch is used, you do not need to modify your input script. -The specified suffix (opt,gpu,cuda) is automatically appended whenever +The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever your input script command creates a new atom, pair, fix, compute, or run style. atom, pair, fix, compute, or integrate diff --git a/doc/Section_start.txt b/doc/Section_start.txt index fad3959e79..5ae3fb715c 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -970,18 +970,18 @@ partition screen files file.N. -suffix style :pre Use variants of various styles if they exist. The specified style can -be {opt} or {gpu} or {cuda}. These refer to optional packages that +be {opt}, {omp}, {gpu}, or {cuda}. These refer to optional packages that LAMMPS can be built with, as described above in "Section 2.3"_#start_3. The "opt" style corrsponds to the OPT package, the -"gpu" style to the GPU package, and the "cuda" style to the USER-CUDA -package. +"omp" style to the USER-OMP package, the "gpu" style to the GPU +package, and the "cuda" style to the USER-CUDA package. As an example, all of the packages provide a "pair_style -lj/cut"_pair_lj.html variant, with style names lj/cut/opt or -lj/cut/gpu or lj/cut/cuda. A variant styles can be specified +lj/cut"_pair_lj.html variant, with style names lj/cut/opt, lj/cut/omp, +lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified explicitly in your input script, e.g. pair_style lj/cut/gpu. If the -suffix switch is used, you do not need to modify your input script. -The specified suffix (opt,gpu,cuda) is automatically appended whenever +The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever your input script command creates a new "atom"_atom_style.html, "pair"_pair_style.html, "fix"_fix.html, "compute"_compute.html, or "run"_run_style.html style. atom, pair, fix, compute, or integrate diff --git a/doc/angle_hybrid.html b/doc/angle_hybrid.html index bd7ff2db01..a9cd04b369 100644 --- a/doc/angle_hybrid.html +++ b/doc/angle_hybrid.html @@ -11,6 +11,8 @@

    angle_style hybrid command

    +

    angle_style hybrid/omp command +

    Syntax:

    angle_style hybrid style1 style2 ... 
    @@ -74,6 +76,34 @@ in place of an angle style, either in a input script angle_coeff
     command or in the data file, if you desire to turn off interactions
     for specific angle types.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +

    +

    Since the hybrid style delegates computation to the individual +sub-styles, the suffix versions of the hybrid styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. +

    +

    The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +Making LAMMPS section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This angle style can only be used if LAMMPS was built with the diff --git a/doc/angle_hybrid.txt b/doc/angle_hybrid.txt index 2996d3ddb8..6662216b4c 100644 --- a/doc/angle_hybrid.txt +++ b/doc/angle_hybrid.txt @@ -7,6 +7,7 @@ :line angle_style hybrid command :h3 +angle_style hybrid/omp command :h3 [Syntax:] @@ -71,6 +72,34 @@ in place of an angle style, either in a input script angle_coeff command or in the data file, if you desire to turn off interactions for specific angle types. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. + +Since the {hybrid} style delegates computation to the individual +sub-styles, the suffix versions of the {hybrid} styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. + +The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +"Making LAMMPS"_Section_start.html#start_3 section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This angle style can only be used if LAMMPS was built with the diff --git a/doc/bond_hybrid.html b/doc/bond_hybrid.html index b9073bd9d1..fc1a85093f 100644 --- a/doc/bond_hybrid.html +++ b/doc/bond_hybrid.html @@ -11,6 +11,8 @@

    bond_style hybrid command

    +

    bond_style hybrid/omp command +

    Syntax:

    bond_style hybrid style1 style2 ... 
    @@ -57,6 +59,34 @@ place of a bond style, either in a input script bond_coeff command or
     in the data file, if you desire to turn off interactions for specific
     bond types.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +

    +

    Since the hybrid style delegates computation to the individual +sub-styles, the suffix versions of the hybrid styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. +

    +

    The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +Making LAMMPS section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This bond style can only be used if LAMMPS was built with the diff --git a/doc/bond_hybrid.txt b/doc/bond_hybrid.txt index f4a9959229..683e5cd73f 100644 --- a/doc/bond_hybrid.txt +++ b/doc/bond_hybrid.txt @@ -7,6 +7,7 @@ :line bond_style hybrid command :h3 +bond_style hybrid/omp command :h3 [Syntax:] @@ -54,6 +55,34 @@ place of a bond style, either in a input script bond_coeff command or in the data file, if you desire to turn off interactions for specific bond types. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. + +Since the {hybrid} style delegates computation to the individual +sub-styles, the suffix versions of the {hybrid} styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. + +The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +"Making LAMMPS"_Section_start.html#start_3 section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This bond style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_charmm.html b/doc/dihedral_charmm.html index 5a30dd7a46..6c3104c6e3 100644 --- a/doc/dihedral_charmm.html +++ b/doc/dihedral_charmm.html @@ -11,6 +11,8 @@

    dihedral_style charmm command

    +

    dihedral_style charmm/omp command +

    Syntax:

    dihedral_style charmm 
    @@ -67,6 +69,30 @@ weighting factors (4th coeff above) should be set to 0.0.  In this
     case, you can use any pair style you wish, since the dihedral does not
     need any 1-4 information.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_charmm.txt b/doc/dihedral_charmm.txt index 4105573458..c0b959ffb5 100644 --- a/doc/dihedral_charmm.txt +++ b/doc/dihedral_charmm.txt @@ -7,6 +7,7 @@ :line dihedral_style charmm command :h3 +dihedral_style charmm/omp command :h3 [Syntax:] @@ -64,6 +65,30 @@ weighting factors (4th coeff above) should be set to 0.0. In this case, you can use any pair style you wish, since the dihedral does not need any 1-4 information. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_class2.html b/doc/dihedral_class2.html index 471ccdd17d..79e7b47d92 100644 --- a/doc/dihedral_class2.html +++ b/doc/dihedral_class2.html @@ -11,6 +11,8 @@

    dihedral_style class2 command

    +

    dihedral_style class2/omp command +

    Syntax:

    dihedral_style class2 
    @@ -137,6 +139,30 @@ listed under a "BondBond13 Coeffs" heading and you must leave out the
     
  • r1 (distance)
  • r3 (distance) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_class2.txt b/doc/dihedral_class2.txt index 21e37cb12b..ab60aa3812 100644 --- a/doc/dihedral_class2.txt +++ b/doc/dihedral_class2.txt @@ -7,6 +7,7 @@ :line dihedral_style class2 command :h3 +dihedral_style class2/omp command :h3 [Syntax:] @@ -134,6 +135,30 @@ N (energy/distance^2) r1 (distance) r3 (distance) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_cosine_shift_exp.html b/doc/dihedral_cosine_shift_exp.html index a4927685d0..c6ab2cae79 100644 --- a/doc/dihedral_cosine_shift_exp.html +++ b/doc/dihedral_cosine_shift_exp.html @@ -11,6 +11,8 @@

    dihedral_style cosine/shift/exp command

    +

    dihedral_style cosine/shift/exp/omp command +

    Syntax:

    dihedral_style cosine/shift/exp 
    @@ -49,6 +51,30 @@ commands:
     
  • theta (angle)
  • A (real number) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_cosine_shift_exp.txt b/doc/dihedral_cosine_shift_exp.txt index dd49b2759b..d1e1c8223b 100644 --- a/doc/dihedral_cosine_shift_exp.txt +++ b/doc/dihedral_cosine_shift_exp.txt @@ -7,6 +7,7 @@ :line dihedral_style cosine/shift/exp command :h3 +dihedral_style cosine/shift/exp/omp command :h3 [Syntax:] @@ -46,6 +47,30 @@ umin (energy) theta (angle) A (real number) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_harmonic.html b/doc/dihedral_harmonic.html index 68a8a6bbca..d8c3a73f69 100644 --- a/doc/dihedral_harmonic.html +++ b/doc/dihedral_harmonic.html @@ -11,6 +11,8 @@

    dihedral_style harmonic command

    +

    dihedral_style harmonic/omp command +

    Syntax:

    dihedral_style harmonic 
    @@ -35,6 +37,30 @@ or read_restart commands:
     
  • d (+1 or -1)
  • n (integer >= 0) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_harmonic.txt b/doc/dihedral_harmonic.txt index bb4192f816..a076931a0a 100644 --- a/doc/dihedral_harmonic.txt +++ b/doc/dihedral_harmonic.txt @@ -7,6 +7,7 @@ :line dihedral_style harmonic command :h3 +dihedral_style harmonic/omp command :h3 [Syntax:] @@ -32,6 +33,30 @@ K (energy) d (+1 or -1) n (integer >= 0) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_helix.html b/doc/dihedral_helix.html index 93dd552164..86b3728339 100644 --- a/doc/dihedral_helix.html +++ b/doc/dihedral_helix.html @@ -11,6 +11,8 @@

    dihedral_style helix command

    +

    dihedral_style helix/omp command +

    Syntax:

    dihedral_style helix 
    @@ -43,6 +45,30 @@ or read_restart commands:
     
  • B (energy)
  • C (energy) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_helix.txt b/doc/dihedral_helix.txt index 3ff9b53898..8792c10767 100644 --- a/doc/dihedral_helix.txt +++ b/doc/dihedral_helix.txt @@ -7,6 +7,7 @@ :line dihedral_style helix command :h3 +dihedral_style helix/omp command :h3 [Syntax:] @@ -40,6 +41,30 @@ A (energy) B (energy) C (energy) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_hybrid.html b/doc/dihedral_hybrid.html index 07e9f6ee41..4bee37a9e2 100644 --- a/doc/dihedral_hybrid.html +++ b/doc/dihedral_hybrid.html @@ -11,6 +11,8 @@

    dihedral_style hybrid command

    +

    dihedral_style hybrid/omp command +

    Syntax:

    dihedral_style hybrid style1 style2 ... 
    @@ -75,6 +77,34 @@ in place of a dihedral style, either in a input script dihedral_coeff
     command or in the data file, if you desire to turn off interactions
     for specific dihedral types.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +

    +

    Since the hybrid style delegates computation to the individual +sub-styles, the suffix versions of the hybrid styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. +

    +

    The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +Making LAMMPS section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_hybrid.txt b/doc/dihedral_hybrid.txt index 4ccf8ef057..6a64359db1 100644 --- a/doc/dihedral_hybrid.txt +++ b/doc/dihedral_hybrid.txt @@ -7,6 +7,7 @@ :line dihedral_style hybrid command :h3 +dihedral_style hybrid/omp command :h3 [Syntax:] @@ -72,6 +73,34 @@ in place of a dihedral style, either in a input script dihedral_coeff command or in the data file, if you desire to turn off interactions for specific dihedral types. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. + +Since the {hybrid} style delegates computation to the individual +sub-styles, the suffix versions of the {hybrid} styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. + +The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +"Making LAMMPS"_Section_start.html#start_3 section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_multi_harmonic.html b/doc/dihedral_multi_harmonic.html index f63c22fc24..10601f3362 100644 --- a/doc/dihedral_multi_harmonic.html +++ b/doc/dihedral_multi_harmonic.html @@ -11,6 +11,8 @@

    dihedral_style multi/harmonic command

    +

    dihedral_style multi/harmonic/omp command +

    Syntax:

    dihedral_style multi/harmonic 
    @@ -37,6 +39,30 @@ or read_restart commands:
     
  • A4 (energy)
  • A5 (energy) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_multi_harmonic.txt b/doc/dihedral_multi_harmonic.txt index d0196279bf..505857fe81 100644 --- a/doc/dihedral_multi_harmonic.txt +++ b/doc/dihedral_multi_harmonic.txt @@ -7,6 +7,7 @@ :line dihedral_style multi/harmonic command :h3 +dihedral_style multi/harmonic/omp command :h3 [Syntax:] @@ -34,6 +35,30 @@ A3 (energy) A4 (energy) A5 (energy) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_opls.html b/doc/dihedral_opls.html index 39cd3f6b92..e0656dd837 100644 --- a/doc/dihedral_opls.html +++ b/doc/dihedral_opls.html @@ -11,6 +11,8 @@

    dihedral_style opls command

    +

    dihedral_style opls/omp command +

    Syntax:

    dihedral_style opls 
    @@ -41,6 +43,30 @@ or read_restart commands:
     
  • K3 (energy)
  • K4 (energy) +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_opls.txt b/doc/dihedral_opls.txt index 530201899a..c43e7a279e 100644 --- a/doc/dihedral_opls.txt +++ b/doc/dihedral_opls.txt @@ -7,6 +7,7 @@ :line dihedral_style opls command :h3 +dihedral_style opls/omp command :h3 [Syntax:] @@ -38,6 +39,30 @@ K2 (energy) K3 (energy) K4 (energy) :ul +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/fix_gravity.html b/doc/fix_gravity.html index 7823383666..fbc2fce7f3 100644 --- a/doc/fix_gravity.html +++ b/doc/fix_gravity.html @@ -13,6 +13,8 @@

    fix gravity/cuda command

    +

    fix gravity/omp command +

    Syntax:

    fix ID group gravity style magnitude args 
    @@ -89,16 +91,17 @@ by (x,y,z).  For 2d systems, the z component is ignored.
     


    -

    Styles with a cuda suffix are functionally the same as the -corresponding style without the suffix. They have been optimized to -run faster, depending on your available hardware, as discussed in -this section of the manual. The accelerated -styles take the same arguments and should produce the same results, -except for round-off and precision issues. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA package. They are -only enabled if LAMMPS was built with that package. See the Making -LAMMPS section for more info. +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info.

    You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the -suffix command-line diff --git a/doc/fix_gravity.txt b/doc/fix_gravity.txt index f383755ac5..bad5edc997 100644 --- a/doc/fix_gravity.txt +++ b/doc/fix_gravity.txt @@ -8,6 +8,7 @@ fix gravity command :h3 fix gravity/cuda command :h3 +fix gravity/omp command :h3 [Syntax:] @@ -80,16 +81,17 @@ by (x,y,z). For 2d systems, the z component is ignored. :line -Styles with a {cuda} suffix are functionally the same as the -corresponding style without the suffix. They have been optimized to -run faster, depending on your available hardware, as discussed in -"this section"_Section_accelerate.html of the manual. The accelerated -styles take the same arguments and should produce the same results, -except for round-off and precision issues. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA package. They are -only enabled if LAMMPS was built with that package. See the "Making -LAMMPS"_Section_start.html#start_3 section for more info. +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line diff --git a/doc/fix_nve_sphere.html b/doc/fix_nve_sphere.html index 887985242a..f2f5678cd7 100644 --- a/doc/fix_nve_sphere.html +++ b/doc/fix_nve_sphere.html @@ -11,6 +11,8 @@

    fix nve/sphere command

    +

    fix nve/sphere/omp command +

    Syntax:

    fix ID group-ID nve/sphere 
    @@ -49,6 +51,30 @@ during the time integration.  This option should be used for models
     where a dipole moment is assigned to particles via use of the
     atom_style dipole command.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restart, fix_modify, output, run start/stop, minimize info:

    No information about this fix is written to binary restart diff --git a/doc/fix_nve_sphere.txt b/doc/fix_nve_sphere.txt index 05080e58a1..3c5864d3f4 100755 --- a/doc/fix_nve_sphere.txt +++ b/doc/fix_nve_sphere.txt @@ -7,6 +7,7 @@ :line fix nve/sphere command :h3 +fix nve/sphere/omp command :h3 [Syntax:] @@ -41,6 +42,30 @@ during the time integration. This option should be used for models where a dipole moment is assigned to particles via use of the "atom_style dipole"_atom_style.html command. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart diff --git a/doc/fix_qeq_comb.html b/doc/fix_qeq_comb.html index b6c5d437ff..c66b49dc4d 100644 --- a/doc/fix_qeq_comb.html +++ b/doc/fix_qeq_comb.html @@ -11,6 +11,8 @@

    fix qeq/comb command

    +

    fix qeq/comb/omp command +

    Syntax:

    fix ID group-ID qeq/comb Nevery precision keyword value ... 
    @@ -66,6 +68,30 @@ performing charge equilibration (more iterations) and accuracy.
     

    If the file keyword is used, then information about each equilibration calculation is written to the specifed file.

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restart, fix_modify, output, run start/stop, minimize info:

    No information about this fix is written to binary restart diff --git a/doc/fix_qeq_comb.txt b/doc/fix_qeq_comb.txt index 8c8e53d039..3fbb9dc7b9 100644 --- a/doc/fix_qeq_comb.txt +++ b/doc/fix_qeq_comb.txt @@ -7,6 +7,7 @@ :line fix qeq/comb command :h3 +fix qeq/comb/omp command :h3 [Syntax:] @@ -56,6 +57,30 @@ performing charge equilibration (more iterations) and accuracy. If the {file} keyword is used, then information about each equilibration calculation is written to the specifed file. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart diff --git a/doc/improper_hybrid.html b/doc/improper_hybrid.html index 52b68f4bda..e00479867f 100644 --- a/doc/improper_hybrid.html +++ b/doc/improper_hybrid.html @@ -11,6 +11,8 @@

    improper_style hybrid command

    +

    improper_style hybrid/omp command +

    Syntax:

    improper_style hybrid style1 style2 ... 
    @@ -53,6 +55,34 @@ type will then be ignored.
     the improper_coeff command, if you desire to turn off certain improper
     types.
     

    +
    + +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +

    +

    Since the hybrid style delegates computation to the individual +sub-styles, the suffix versions of the hybrid styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. +

    +

    The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +Making LAMMPS section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This improper style can only be used if LAMMPS was built with the diff --git a/doc/improper_hybrid.txt b/doc/improper_hybrid.txt index ee9dfc5718..77d62b2e64 100644 --- a/doc/improper_hybrid.txt +++ b/doc/improper_hybrid.txt @@ -7,6 +7,7 @@ :line improper_style hybrid command :h3 +improper_style hybrid/omp command :h3 [Syntax:] @@ -50,6 +51,34 @@ An improper style of {none} can be specified as the 2nd argument to the improper_coeff command, if you desire to turn off certain improper types. +:line + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. + +Since the {hybrid} style delegates computation to the individual +sub-styles, the suffix versions of the {hybrid} styles are used +to propagate the corresponding suffix to all sub-styles, if those +accelerated versions exist. Otherwise the non-accelerated version +will be used. + +The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +"Making LAMMPS"_Section_start.html#start_3 section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This improper style can only be used if LAMMPS was built with the diff --git a/doc/pair_adp.html b/doc/pair_adp.html index 1013ed6d75..34bf494229 100644 --- a/doc/pair_adp.html +++ b/doc/pair_adp.html @@ -11,6 +11,8 @@

    pair_style adp command

    +

    pair_style adp/omp command +

    Syntax:

    pair_style adp 
    @@ -118,6 +120,28 @@ the u(r), the w(r) arrays are listed.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_adp.txt b/doc/pair_adp.txt index cf66af91ca..4eef1d675e 100644 --- a/doc/pair_adp.txt +++ b/doc/pair_adp.txt @@ -7,6 +7,7 @@ :line pair_style adp command :h3 +pair_style adp/omp command :h3 [Syntax:] @@ -115,6 +116,28 @@ the u(r), the w(r) arrays are listed. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_airebo.html b/doc/pair_airebo.html index 290245bed3..282e1affbf 100644 --- a/doc/pair_airebo.html +++ b/doc/pair_airebo.html @@ -11,8 +11,12 @@

    pair_style airebo command

    +

    pair_style airebo/omp command +

    pair_style rebo command

    +

    pair_style rebo/omp command +

    Syntax:

    pair_style style cutoff LJ_flag TORSION_flag 
    @@ -120,6 +124,28 @@ it was fit, so modifying the file should be done cautiously.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    These pair styles do not support the pair_modify diff --git a/doc/pair_airebo.txt b/doc/pair_airebo.txt index 5d552132fd..71c7ea071a 100644 --- a/doc/pair_airebo.txt +++ b/doc/pair_airebo.txt @@ -7,7 +7,9 @@ :line pair_style airebo command :h3 +pair_style airebo/omp command :h3 pair_style rebo command :h3 +pair_style rebo/omp command :h3 [Syntax:] @@ -116,6 +118,28 @@ it was fit, so modifying the file should be done cautiously. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: These pair styles do not support the "pair_modify"_pair_modify.html diff --git a/doc/pair_born.html b/doc/pair_born.html index e396552aad..e5d4038a78 100644 --- a/doc/pair_born.html +++ b/doc/pair_born.html @@ -11,10 +11,14 @@

    pair_style born command

    +

    pair_style born/omp command +

    pair_style born/coul/long command

    pair_style born/coul/long/cuda command

    +

    pair_style born/coul/long/omp command +

    Syntax:

    pair_style style args 
    @@ -89,15 +93,15 @@ Coulombic cutoff specified in the pair_style command.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_born.txt b/doc/pair_born.txt index 56e1515dae..652e7b4dda 100644 --- a/doc/pair_born.txt +++ b/doc/pair_born.txt @@ -8,8 +8,10 @@ :line pair_style born command :h3 +pair_style born/omp command :h3 pair_style born/coul/long command :h3 pair_style born/coul/long/cuda command :h3 +pair_style born/coul/long/omp command :h3 [Syntax:] @@ -84,15 +86,15 @@ Coulombic cutoff specified in the pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_buck.html b/doc/pair_buck.html index b0d50311ee..a7b8c76aac 100644 --- a/doc/pair_buck.html +++ b/doc/pair_buck.html @@ -13,14 +13,20 @@

    pair_style buck/cuda command

    +

    pair_style buck/omp command +

    pair_style buck/coul/cut command

    pair_style buck/coul/cut/cuda command

    +

    pair_style buck/coul/cut/omp command +

    pair_style buck/coul/long command

    pair_style buck/coul/long/cuda command

    +

    pair_style buck/coul/long/omp command +

    Syntax:

    pair_style style args 
    @@ -110,15 +116,15 @@ pair_style command.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_buck.txt b/doc/pair_buck.txt index 40e095fb64..1f875f9ac4 100644 --- a/doc/pair_buck.txt +++ b/doc/pair_buck.txt @@ -8,10 +8,13 @@ pair_style buck command :h3 pair_style buck/cuda command :h3 +pair_style buck/omp command :h3 pair_style buck/coul/cut command :h3 pair_style buck/coul/cut/cuda command :h3 +pair_style buck/coul/cut/omp command :h3 pair_style buck/coul/long command :h3 pair_style buck/coul/long/cuda command :h3 +pair_style buck/coul/long/omp command :h3 [Syntax:] @@ -101,15 +104,15 @@ pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_buck_coul.html b/doc/pair_buck_coul.html index cfb237e58d..149fe36e3d 100644 --- a/doc/pair_buck_coul.html +++ b/doc/pair_buck_coul.html @@ -11,6 +11,8 @@

    pair_style buck/coul command

    +

    pair_style buck/coul/omp command +

    Syntax:

    pair_style buck/coul flag_buck flag_coul cutoff (cutoff2) 
    @@ -103,6 +105,28 @@ global Coulombic cutoff is allowed.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    This pair styles does not support mixing. Thus, coefficients for all diff --git a/doc/pair_buck_coul.txt b/doc/pair_buck_coul.txt index 16638246a9..4db2117094 100644 --- a/doc/pair_buck_coul.txt +++ b/doc/pair_buck_coul.txt @@ -7,6 +7,7 @@ :line pair_style buck/coul command :h3 +pair_style buck/coul/omp command :h3 [Syntax:] @@ -95,6 +96,28 @@ global Coulombic cutoff is allowed. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair styles does not support mixing. Thus, coefficients for all diff --git a/doc/pair_charmm.html b/doc/pair_charmm.html index 0f1b7c572e..50dcbe5e7d 100644 --- a/doc/pair_charmm.html +++ b/doc/pair_charmm.html @@ -13,10 +13,14 @@

    pair_style lj/charmm/coul/charmm/cuda command

    +

    pair_style lj/charmm/coul/charmm/omp command +

    pair_style lj/charmm/coul/charmm/implicit command

    pair_style lj/charmm/coul/charmm/implicit/cuda command

    +

    pair_style lj/charmm/coul/charmm/implicit/omp command +

    pair_style lj/charmm/coul/long command

    pair_style lj/charmm/coul/long/cuda command @@ -25,6 +29,8 @@

    pair_style lj/charmm/coul/long/opt command

    +

    pair_style lj/charmm/coul/long/omp command +

    Syntax:

    pair_style style args 
    @@ -117,15 +123,15 @@ the pair_style command.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_charmm.txt b/doc/pair_charmm.txt index 7e38167b27..08fe292579 100644 --- a/doc/pair_charmm.txt +++ b/doc/pair_charmm.txt @@ -8,12 +8,15 @@ pair_style lj/charmm/coul/charmm command :h3 pair_style lj/charmm/coul/charmm/cuda command :h3 +pair_style lj/charmm/coul/charmm/omp command :h3 pair_style lj/charmm/coul/charmm/implicit command :h3 pair_style lj/charmm/coul/charmm/implicit/cuda command :h3 +pair_style lj/charmm/coul/charmm/implicit/omp command :h3 pair_style lj/charmm/coul/long command :h3 pair_style lj/charmm/coul/long/cuda command :h3 pair_style lj/charmm/coul/long/gpu command :h3 pair_style lj/charmm/coul/long/opt command :h3 +pair_style lj/charmm/coul/long/omp command :h3 [Syntax:] @@ -106,15 +109,15 @@ the pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_class2.html b/doc/pair_class2.html index f379c35fcc..b4fc597158 100644 --- a/doc/pair_class2.html +++ b/doc/pair_class2.html @@ -15,16 +15,22 @@

    pair_style lj/class2/gpu command

    +

    pair_style lj/class2/omp command +

    pair_style lj/class2/coul/cut command

    pair_style lj/class2/coul/cut/cuda command

    +

    pair_style lj/class2/coul/cut/omp command +

    pair_style lj/class2/coul/long command

    pair_style lj/class2/coul/long/cuda command

    pair_style lj/class2/coul/long/gpu command

    +

    pair_style lj/class2/coul/long/omp command +

    Syntax:

    pair_style style args 
    @@ -108,15 +114,15 @@ cutoff distance.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    @@ -128,6 +134,8 @@ use the suffix command in your input script.

    See this section of the manual for more instructions on how to use the accelerated styles effectively.

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_class2.txt b/doc/pair_class2.txt index 881b458f35..3013727493 100644 --- a/doc/pair_class2.txt +++ b/doc/pair_class2.txt @@ -9,11 +9,14 @@ pair_style lj/class2 command :h3 pair_style lj/class2/cuda command :h3 pair_style lj/class2/gpu command :h3 +pair_style lj/class2/omp command :h3 pair_style lj/class2/coul/cut command :h3 pair_style lj/class2/coul/cut/cuda command :h3 +pair_style lj/class2/coul/cut/omp command :h3 pair_style lj/class2/coul/long command :h3 pair_style lj/class2/coul/long/cuda command :h3 pair_style lj/class2/coul/long/gpu command :h3 +pair_style lj/class2/coul/long/omp command :h3 [Syntax:] @@ -97,15 +100,15 @@ cutoff distance. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. @@ -117,6 +120,8 @@ use the "suffix"_suffix.html command in your input script. See "this section"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_colloid.html b/doc/pair_colloid.html index 7fb70fa85f..a1754fd5df 100644 --- a/doc/pair_colloid.html +++ b/doc/pair_colloid.html @@ -11,6 +11,8 @@

    pair_style colloid command

    +

    pair_style colloid/omp command +

    Syntax:

    pair_style colloid cutoff 
    @@ -125,6 +127,28 @@ commands for efficiency: neighbor multi and
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the A, sigma, d1, and d2 diff --git a/doc/pair_colloid.txt b/doc/pair_colloid.txt index 7a519852e8..8a442ea078 100644 --- a/doc/pair_colloid.txt +++ b/doc/pair_colloid.txt @@ -7,6 +7,7 @@ :line pair_style colloid command :h3 +pair_style colloid/omp command :h3 [Syntax:] @@ -122,6 +123,28 @@ commands for efficiency: "neighbor multi"_neighbor.html and :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the A, sigma, d1, and d2 diff --git a/doc/pair_comb.html b/doc/pair_comb.html index 3c2f35f354..71e245c9e6 100644 --- a/doc/pair_comb.html +++ b/doc/pair_comb.html @@ -11,6 +11,8 @@

    pair_style comb command

    +

    pair_style comb/omp command +

    Syntax:

    pair_style comb 
    @@ -167,6 +169,28 @@ complex systems.  Note that alloys and complex systems require all
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_comb.txt b/doc/pair_comb.txt index 0b2cb0ae11..ed625ba629 100644 --- a/doc/pair_comb.txt +++ b/doc/pair_comb.txt @@ -7,6 +7,7 @@ :line pair_style comb command :h3 +pair_style comb/omp command :h3 [Syntax:] @@ -164,6 +165,28 @@ complex systems. Note that alloys and complex systems require all :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_coul.html b/doc/pair_coul.html index b0d9d858ce..6b6af23458 100644 --- a/doc/pair_coul.html +++ b/doc/pair_coul.html @@ -11,19 +11,24 @@

    pair_style coul/cut command

    +

    pair_style coul/cut/omp command +

    pair_style coul/debye command

    +

    pair_style coul/debye/omp command +

    pair_style coul/long command

    pair_style coul/long/gpu command

    +

    pair_style coul/long/omp command +

    Syntax:

    -
    pair_style coul/cut cutoff
    +

    pair_style coul/cut cutoff pair_style coul/debye kappa cutoff pair_style coul/long cutoff -pair_style coul/long/gpu cutoff -

    +

    • cutoff = global cutoff for Coulombic interactions
    • kappa = Debye length (inverse distance units)
    @@ -92,15 +97,15 @@ Coulombic cutoff specified in the pair_style command.


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_coul.txt b/doc/pair_coul.txt index 4fb60c2693..6e5e7a54ab 100644 --- a/doc/pair_coul.txt +++ b/doc/pair_coul.txt @@ -7,16 +7,18 @@ :line pair_style coul/cut command :h3 +pair_style coul/cut/omp command :h3 pair_style coul/debye command :h3 +pair_style coul/debye/omp command :h3 pair_style coul/long command :h3 pair_style coul/long/gpu command :h3 +pair_style coul/long/omp command :h3 [Syntax:] pair_style coul/cut cutoff pair_style coul/debye kappa cutoff pair_style coul/long cutoff -pair_style coul/long/gpu cutoff :pre cutoff = global cutoff for Coulombic interactions kappa = Debye length (inverse distance units) :ul @@ -86,15 +88,15 @@ Coulombic cutoff specified in the pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_dipole.html b/doc/pair_dipole.html index 99d02a36e0..0c259887b2 100644 --- a/doc/pair_dipole.html +++ b/doc/pair_dipole.html @@ -11,8 +11,12 @@

    pair_style dipole/cut command

    +

    pair_style dipole/cut/omp command +

    pair_style dipole/sf command

    +

    pair_style dipole/sf/omp command +

    Syntax:

    pair_style dipole/cut cutoff (cutoff2) 
    @@ -120,6 +124,28 @@ type pair.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_dipole.txt b/doc/pair_dipole.txt index bb735d7a45..d71ffef2e0 100755 --- a/doc/pair_dipole.txt +++ b/doc/pair_dipole.txt @@ -7,7 +7,9 @@ :line pair_style dipole/cut command :h3 +pair_style dipole/cut/omp command :h3 pair_style dipole/sf command :h3 +pair_style dipole/sf/omp command :h3 [Syntax:] @@ -114,6 +116,28 @@ type pair. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_dpd.html b/doc/pair_dpd.html index 065b8c73d3..40d1dae1f0 100644 --- a/doc/pair_dpd.html +++ b/doc/pair_dpd.html @@ -11,8 +11,12 @@

    pair_style dpd command

    +

    pair_style dpd/omp command +

    pair_style dpd/tstat command

    +

    pair_style dpd/tstat/omp command +

    Syntax:

    pair_style dpd T cutoff seed
    @@ -94,6 +98,28 @@ except that A is not included.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    These pair styles do not support mixing. Thus, coefficients for all diff --git a/doc/pair_dpd.txt b/doc/pair_dpd.txt index 4b2d1081d6..2b60a59375 100644 --- a/doc/pair_dpd.txt +++ b/doc/pair_dpd.txt @@ -7,7 +7,9 @@ :line pair_style dpd command :h3 +pair_style dpd/omp command :h3 pair_style dpd/tstat command :h3 +pair_style dpd/tstat/omp command :h3 [Syntax:] @@ -90,6 +92,28 @@ except that A is not included. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: These pair styles do not support mixing. Thus, coefficients for all diff --git a/doc/pair_eam.html b/doc/pair_eam.html index 3584d06a9e..4f695c52e0 100644 --- a/doc/pair_eam.html +++ b/doc/pair_eam.html @@ -13,20 +13,28 @@

    pair_style eam/cuda command

    +

    pair_style eam/omp command +

    pair_style eam/opt command

    pair_style eam/alloy command

    pair_style eam/alloy/cuda command

    +

    pair_style eam/alloy/omp command +

    pair_style eam/alloy/opt command

    pair_style eam/cd command

    +

    pair_style eam/cd/omp command +

    pair_style eam/fs command

    pair_style eam/fs/cuda command

    +

    pair_style eam/fs/omp command +

    pair_style eam/fs/opt command

    Syntax: @@ -365,15 +373,15 @@ are listed.


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_eam.txt b/doc/pair_eam.txt index 5bc1779cb9..d0b06bf07b 100644 --- a/doc/pair_eam.txt +++ b/doc/pair_eam.txt @@ -8,13 +8,17 @@ pair_style eam command :h3 pair_style eam/cuda command :h3 +pair_style eam/omp command :h3 pair_style eam/opt command :h3 pair_style eam/alloy command :h3 pair_style eam/alloy/cuda command :h3 +pair_style eam/alloy/omp command :h3 pair_style eam/alloy/opt command :h3 pair_style eam/cd command :h3 +pair_style eam/cd/omp command :h3 pair_style eam/fs command :h3 pair_style eam/fs/cuda command :h3 +pair_style eam/fs/omp command :h3 pair_style eam/fs/opt command :h3 [Syntax:] @@ -353,15 +357,16 @@ are listed. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. + +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_edip.html b/doc/pair_edip.html index 4a46880dd9..1c09c8ed49 100644 --- a/doc/pair_edip.html +++ b/doc/pair_edip.html @@ -15,6 +15,8 @@

    pair_style edip 
     
    +
    pair_style edip/omp 
    +

    Examples:

    pair_style edip @@ -100,6 +102,28 @@ the EDIP package.


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    This pair style does not support the pair_modify diff --git a/doc/pair_edip.txt b/doc/pair_edip.txt index af36fdd0b8..3494ce68f8 100644 --- a/doc/pair_edip.txt +++ b/doc/pair_edip.txt @@ -11,6 +11,7 @@ pair_style edip command :h3 [Syntax:] pair_style edip :pre +pair_style edip/omp :pre [Examples:] @@ -97,6 +98,28 @@ the EDIP package. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support the "pair_modify"_pair_modify.html diff --git a/doc/pair_eim.html b/doc/pair_eim.html index b43368617c..484cb2505c 100644 --- a/doc/pair_eim.html +++ b/doc/pair_eim.html @@ -11,6 +11,8 @@

    pair_style eim command

    +

    pair_style eim/omp command +

    Syntax:

    pair_style style 
    @@ -132,6 +134,28 @@ needs.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Restrictions:

    This style is part of the MANYBODY package. It is only enabled if diff --git a/doc/pair_eim.txt b/doc/pair_eim.txt index 240e551b85..21c0540058 100644 --- a/doc/pair_eim.txt +++ b/doc/pair_eim.txt @@ -7,6 +7,7 @@ :line pair_style eim command :h3 +pair_style eim/omp command :h3 [Syntax:] @@ -129,6 +130,28 @@ needs. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Restrictions:] This style is part of the MANYBODY package. It is only enabled if diff --git a/doc/pair_gauss.html b/doc/pair_gauss.html index c6ceaae2ae..4a5f91c30e 100644 --- a/doc/pair_gauss.html +++ b/doc/pair_gauss.html @@ -11,6 +11,8 @@

    pair_style gauss command

    +

    pair_style gauss/omp command +

    Syntax:

    pair_style gauss cutoff 
    @@ -47,6 +49,28 @@ is used.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    This pair style does not support mixing. Thus, coefficients for all diff --git a/doc/pair_gauss.txt b/doc/pair_gauss.txt index 85fa1feea5..e3e5b19d66 100644 --- a/doc/pair_gauss.txt +++ b/doc/pair_gauss.txt @@ -7,6 +7,7 @@ :line pair_style gauss command :h3 +pair_style gauss/omp command :h3 [Syntax:] @@ -44,6 +45,28 @@ is used. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support mixing. Thus, coefficients for all diff --git a/doc/pair_gayberne.html b/doc/pair_gayberne.html index e3d249ae4b..ff4e001ced 100644 --- a/doc/pair_gayberne.html +++ b/doc/pair_gayberne.html @@ -13,6 +13,8 @@

    pair_style gayberne/gpu command

    +

    pair_style gayberne/omp command +

    Syntax:

    pair_style gayberne gamma upsilon mu cutoff 
    @@ -132,15 +134,15 @@ pair_coeff sigma to 1.0 as well.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_gayberne.txt b/doc/pair_gayberne.txt index 6ff0f16dd5..9b3363c000 100755 --- a/doc/pair_gayberne.txt +++ b/doc/pair_gayberne.txt @@ -8,6 +8,7 @@ pair_style gayberne command :h3 pair_style gayberne/gpu command :h3 +pair_style gayberne/omp command :h3 [Syntax:] @@ -128,15 +129,15 @@ pair_coeff sigma to 1.0 as well. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_gran.html b/doc/pair_gran.html index 9e1bd6cddf..2c0056f522 100644 --- a/doc/pair_gran.html +++ b/doc/pair_gran.html @@ -13,10 +13,16 @@

    pair_style gran/cuda command

    +

    pair_style gran/omp command +

    pair_style gran/hooke/history command

    +

    pair_style gran/hooke/history/omp command +

    pair_style gran/hertz/history command

    +

    pair_style gran/hertz/history/omp command +

    Syntax:

    pair_style style Kn Kt gamma_n gamma_t xmu dampflag 
    @@ -170,15 +176,15 @@ potential.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_gran.txt b/doc/pair_gran.txt index ec11abea35..d495c010f0 100644 --- a/doc/pair_gran.txt +++ b/doc/pair_gran.txt @@ -8,8 +8,11 @@ pair_style gran/hooke command :h3 pair_style gran/cuda command :h3 +pair_style gran/omp command :h3 pair_style gran/hooke/history command :h3 +pair_style gran/hooke/history/omp command :h3 pair_style gran/hertz/history command :h3 +pair_style gran/hertz/history/omp command :h3 [Syntax:] @@ -159,15 +162,15 @@ potential. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_gromacs.html b/doc/pair_gromacs.html index 9b17b09936..aa8051d5c0 100644 --- a/doc/pair_gromacs.html +++ b/doc/pair_gromacs.html @@ -13,10 +13,14 @@

    pair_style lj/gromacs/cuda command

    +

    pair_style lj/gromacs/omp command +

    pair_style lj/gromacs/coul/gromacs command

    pair_style lj/gromacs/coul/gromacs/cuda command

    +

    pair_style lj/gromacs/coul/gromacs/omp command +

    Syntax:

    pair_style style args 
    @@ -92,15 +96,15 @@ cutoff(s) specified in the pair_style command.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_gromacs.txt b/doc/pair_gromacs.txt index a57253568e..5fc8ef3c4b 100644 --- a/doc/pair_gromacs.txt +++ b/doc/pair_gromacs.txt @@ -8,8 +8,10 @@ pair_style lj/gromacs command :h3 pair_style lj/gromacs/cuda command :h3 +pair_style lj/gromacs/omp command :h3 pair_style lj/gromacs/coul/gromacs command :h3 pair_style lj/gromacs/coul/gromacs/cuda command :h3 +pair_style lj/gromacs/coul/gromacs/omp command :h3 [Syntax:] @@ -85,15 +87,15 @@ cutoff(s) specified in the pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_hbond_dreiding.html b/doc/pair_hbond_dreiding.html index 624b0c22b8..d412af1ef6 100644 --- a/doc/pair_hbond_dreiding.html +++ b/doc/pair_hbond_dreiding.html @@ -11,8 +11,12 @@

    pair_style hbond/dreiding/lj command

    +

    pair_style hbond/dreiding/lj/omp command +

    pair_style hbond/dreiding/morse command

    +

    pair_style hbond/dreiding/morse/omp command +

    Syntax:

    pair_style style N inner_distance_cutoff outer_distance_cutoff angle_cutof 
    @@ -148,6 +152,28 @@ optional parameters.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    These pair styles do not support mixing. You must explicitly identify diff --git a/doc/pair_hbond_dreiding.txt b/doc/pair_hbond_dreiding.txt index 8f7c09f1f0..afc469a4a3 100644 --- a/doc/pair_hbond_dreiding.txt +++ b/doc/pair_hbond_dreiding.txt @@ -7,7 +7,9 @@ :line pair_style hbond/dreiding/lj command :h3 +pair_style hbond/dreiding/lj/omp command :h3 pair_style hbond/dreiding/morse command :h3 +pair_style hbond/dreiding/morse/omp command :h3 [Syntax:] @@ -144,6 +146,28 @@ optional parameters. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: These pair styles do not support mixing. You must explicitly identify diff --git a/doc/pair_hybrid.html b/doc/pair_hybrid.html index 8c5688c3a4..7fcba348da 100644 --- a/doc/pair_hybrid.html +++ b/doc/pair_hybrid.html @@ -11,8 +11,12 @@

    pair_style hybrid command

    +

    pair_style hybrid/omp command +

    pair_style hybrid/overlay command

    +

    pair_style hybrid/overlay/omp command +

    Syntax:

    pair_style hybrid style1 args style2 args ...
    @@ -212,6 +216,32 @@ passed to the Tersoff potential, which means it would compute no
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +

    +

    Since the hybrid and hybrid/overlay styles delegate computation +to the individual sub-styles, the suffix versions of the hybrid +and hybrid/overlay styles are used to propagate the corresponding +suffix to all sub-styles, if those versions exist. Otherwise the +non-accelerated version will be used. +

    +

    The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +Making LAMMPS section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    Any pair potential settings made via the diff --git a/doc/pair_hybrid.txt b/doc/pair_hybrid.txt index 099f5e39ea..b93fe360d8 100644 --- a/doc/pair_hybrid.txt +++ b/doc/pair_hybrid.txt @@ -7,7 +7,9 @@ :line pair_style hybrid command :h3 +pair_style hybrid/omp command :h3 pair_style hybrid/overlay command :h3 +pair_style hybrid/overlay/omp command :h3 [Syntax:] @@ -208,6 +210,32 @@ passed to the Tersoff potential, which means it would compute no :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. + +Since the {hybrid} and {hybrid/overlay} styles delegate computation +to the individual sub-styles, the suffix versions of the {hybrid} +and {hybrid/overlay} styles are used to propagate the corresponding +suffix to all sub-styles, if those versions exist. Otherwise the +non-accelerated version will be used. + +The individual accelerated sub-styles are part of the USER-CUDA, GPU, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the +"Making LAMMPS"_Section_start.html#start_3 section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: Any pair potential settings made via the diff --git a/doc/pair_lj.html b/doc/pair_lj.html index 9283346637..760e03f9f4 100644 --- a/doc/pair_lj.html +++ b/doc/pair_lj.html @@ -19,16 +19,22 @@

    pair_style lj/cut/opt command

    +

    pair_style lj/cut/omp command +

    pair_style lj/cut/coul/cut command

    pair_style lj/cut/coul/cut/cuda command

    pair_style lj/cut/coul/cut/gpu command

    +

    pair_style lj/cut/coul/cut/omp command +

    pair_style lj/cut/coul/debye command

    pair_style lj/cut/coul/debye/cuda command

    +

    pair_style lj/cut/coul/debye/omp command +

    pair_style lj/cut/coul/long command

    pair_style lj/cut/coul/long/cuda command @@ -37,8 +43,12 @@

    pair_style lj/cut/coul/long/opt command

    +

    pair_style lj/cut/coul/long/omp command +

    pair_style lj/cut/coul/long/tip4p command

    +

    pair_style lj/cut/coul/long/tip4p/omp command +

    pair_style lj/cut/coul/long/tip4p/opt command

    Syntax: @@ -177,15 +187,15 @@ Coulombic cutoff specified in the pair_style command.


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_lj.txt b/doc/pair_lj.txt index fb97f627d1..382af5b8a1 100644 --- a/doc/pair_lj.txt +++ b/doc/pair_lj.txt @@ -11,16 +11,21 @@ pair_style lj/cut/cuda command :h3 pair_style lj/cut/experimental/cuda command :h3 pair_style lj/cut/gpu command :h3 pair_style lj/cut/opt command :h3 +pair_style lj/cut/omp command :h3 pair_style lj/cut/coul/cut command :h3 pair_style lj/cut/coul/cut/cuda command :h3 pair_style lj/cut/coul/cut/gpu command :h3 +pair_style lj/cut/coul/cut/omp command :h3 pair_style lj/cut/coul/debye command :h3 pair_style lj/cut/coul/debye/cuda command :h3 +pair_style lj/cut/coul/debye/omp command :h3 pair_style lj/cut/coul/long command :h3 pair_style lj/cut/coul/long/cuda command :h3 pair_style lj/cut/coul/long/gpu command :h3 pair_style lj/cut/coul/long/opt command :h3 +pair_style lj/cut/coul/long/omp command :h3 pair_style lj/cut/coul/long/tip4p command :h3 +pair_style lj/cut/coul/long/tip4p/omp command :h3 pair_style lj/cut/coul/long/tip4p/opt command :h3 [Syntax:] @@ -158,15 +163,15 @@ Coulombic cutoff specified in the pair_style command. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_lj96.html b/doc/pair_lj96.html index f32391b9af..97d794d73e 100644 --- a/doc/pair_lj96.html +++ b/doc/pair_lj96.html @@ -15,6 +15,8 @@

    pair_style lj96/cut/gpu command

    +

    pair_style lj96/cut/omp command +

    Syntax:

    pair_style lj96/cut cutoff 
    @@ -51,15 +53,15 @@ cutoff specified in the pair_style command is used.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_lj96.txt b/doc/pair_lj96.txt index 96fe64076e..dcdb3632c5 100644 --- a/doc/pair_lj96.txt +++ b/doc/pair_lj96.txt @@ -9,6 +9,7 @@ pair_style lj96/cut command :h3 pair_style lj96/cut/cuda command :h3 pair_style lj96/cut/gpu command :h3 +pair_style lj96/cut/omp command :h3 [Syntax:] @@ -46,15 +47,15 @@ cutoff specified in the pair_style command is used. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_lj_coul.html b/doc/pair_lj_coul.html index b495c4d564..9faaba8715 100644 --- a/doc/pair_lj_coul.html +++ b/doc/pair_lj_coul.html @@ -11,6 +11,8 @@

    pair_style lj/coul command

    +

    pair_style lj/coul/omp command +

    Syntax:

    pair_style lj/coul flag_lj flag_coul cutoff (cutoff2) 
    @@ -105,6 +107,28 @@ pair, since only one global Coulombic cutoff is allowed.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_lj_coul.txt b/doc/pair_lj_coul.txt index e731ee3424..1593ca4170 100644 --- a/doc/pair_lj_coul.txt +++ b/doc/pair_lj_coul.txt @@ -7,6 +7,7 @@ :line pair_style lj/coul command :h3 +pair_style lj/coul/omp command :h3 [Syntax:] @@ -97,6 +98,28 @@ pair, since only one global Coulombic cutoff is allowed. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html index 53451ca6b3..b5d72b8452 100644 --- a/doc/pair_lj_cubic.html +++ b/doc/pair_lj_cubic.html @@ -11,6 +11,8 @@

    pair_style lj/cubic command

    +

    pair_style lj/cubic/omp command +

    Syntax:

    pair_style lj/cubic 
    @@ -62,6 +64,28 @@ so rmin = 1.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt index 561c95232f..5d60cb12b4 100644 --- a/doc/pair_lj_cubic.txt +++ b/doc/pair_lj_cubic.txt @@ -7,6 +7,7 @@ :line pair_style lj/cubic command :h3 +pair_style lj/cubic/omp command :h3 [Syntax:] @@ -59,6 +60,28 @@ so rmin = 1. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the epsilon and sigma coefficients diff --git a/doc/pair_lj_expand.html b/doc/pair_lj_expand.html index 29b56468cb..9173bc7d5b 100644 --- a/doc/pair_lj_expand.html +++ b/doc/pair_lj_expand.html @@ -15,6 +15,8 @@

    pair_style lj/expand/gpu command

    +

    pair_style lj/expand/omp command +

    Syntax:

    pair_style lj/expand cutoff 
    @@ -55,15 +57,15 @@ optional.  If not specified, the global LJ cutoff is used.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_lj_expand.txt b/doc/pair_lj_expand.txt index 4efad12035..fc9fd047e0 100644 --- a/doc/pair_lj_expand.txt +++ b/doc/pair_lj_expand.txt @@ -9,6 +9,7 @@ pair_style lj/expand command :h3 pair_style lj/expand/cuda command :h3 pair_style lj/expand/gpu command :h3 +pair_style lj/expand/omp command :h3 [Syntax:] @@ -50,15 +51,15 @@ optional. If not specified, the global LJ cutoff is used. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_lj_sf.html b/doc/pair_lj_sf.html index 71034f6139..7ff9011052 100644 --- a/doc/pair_lj_sf.html +++ b/doc/pair_lj_sf.html @@ -11,6 +11,8 @@

    pair_style lj/sf command

    +

    pair_style lj/sf/omp command +

    Syntax:

    pair_style lj/sf cutoff 
    @@ -46,6 +48,28 @@ LJ cutoff specified in the pair_style command is used.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the epsilon and sigma diff --git a/doc/pair_lj_sf.txt b/doc/pair_lj_sf.txt index aade3f97a5..a56cf7485a 100644 --- a/doc/pair_lj_sf.txt +++ b/doc/pair_lj_sf.txt @@ -7,6 +7,7 @@ :line pair_style lj/sf command :h3 +pair_style lj/sf/omp command :h3 [Syntax:] @@ -43,6 +44,28 @@ LJ cutoff specified in the pair_style command is used. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the epsilon and sigma diff --git a/doc/pair_lj_smooth.html b/doc/pair_lj_smooth.html index bffb1716ec..0805dd5f05 100644 --- a/doc/pair_lj_smooth.html +++ b/doc/pair_lj_smooth.html @@ -13,6 +13,8 @@

    pair_style lj/smooth/cuda command

    +

    pair_style lj/smooth/omp command +

    Syntax:

    pair_style lj/smooth Rin Rc 
    @@ -63,15 +65,15 @@ specified, the global values for Rin and Rc are used.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_lj_smooth.txt b/doc/pair_lj_smooth.txt index 5bbf2c48d8..b08bb47431 100644 --- a/doc/pair_lj_smooth.txt +++ b/doc/pair_lj_smooth.txt @@ -8,6 +8,7 @@ pair_style lj/smooth command :h3 pair_style lj/smooth/cuda command :h3 +pair_style lj/smooth/omp command :h3 [Syntax:] @@ -59,15 +60,15 @@ specified, the global values for Rin and Rc are used. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_lubricate.html b/doc/pair_lubricate.html index 63df12a6d8..0605657b2c 100644 --- a/doc/pair_lubricate.html +++ b/doc/pair_lubricate.html @@ -11,6 +11,8 @@

    pair_style lubricate command

    +

    pair_style lubricate/omp command +

    Syntax:

    pair_style lubricate mu squeeze shear pump twist cutinner cutoff T_target seed 
    @@ -96,6 +98,28 @@ must be specified.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the two cutoff distances for this diff --git a/doc/pair_lubricate.txt b/doc/pair_lubricate.txt index b8f758cb8d..c244dae435 100644 --- a/doc/pair_lubricate.txt +++ b/doc/pair_lubricate.txt @@ -7,6 +7,7 @@ :line pair_style lubricate command :h3 +pair_style lubricate/omp command :h3 [Syntax:] @@ -93,6 +94,28 @@ must be specified. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the two cutoff distances for this diff --git a/doc/pair_morse.html b/doc/pair_morse.html index bdb1af6548..eaf5f16085 100644 --- a/doc/pair_morse.html +++ b/doc/pair_morse.html @@ -15,6 +15,8 @@

    pair_style morse/gpu command

    +

    pair_style morse/omp command +

    pair_style morse/opt command

    Syntax: @@ -53,15 +55,15 @@ cutoff is used.


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_morse.txt b/doc/pair_morse.txt index eb9d78cf6d..b31acbb5ac 100644 --- a/doc/pair_morse.txt +++ b/doc/pair_morse.txt @@ -9,6 +9,7 @@ pair_style morse command :h3 pair_style morse/cuda command :h3 pair_style morse/gpu command :h3 +pair_style morse/omp command :h3 pair_style morse/opt command :h3 [Syntax:] @@ -47,15 +48,15 @@ cutoff is used. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_peri.html b/doc/pair_peri.html index 4dbf57a000..33bcbd17c1 100644 --- a/doc/pair_peri.html +++ b/doc/pair_peri.html @@ -11,8 +11,12 @@

    pair_style peri/pmb command

    +

    pair_style peri/pmb/omp command +

    pair_style peri/lps command

    +

    pair_style peri/lps/omp command +

    Syntax:

    pair_style style 
    @@ -79,6 +83,28 @@ details.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    These pair styles do not support mixing. Thus, coefficients for all diff --git a/doc/pair_peri.txt b/doc/pair_peri.txt index 080508b37f..00f6636493 100644 --- a/doc/pair_peri.txt +++ b/doc/pair_peri.txt @@ -7,7 +7,9 @@ :line pair_style peri/pmb command :h3 +pair_style peri/pmb/omp command :h3 pair_style peri/lps command :h3 +pair_style peri/lps/omp command :h3 [Syntax:] @@ -75,6 +77,28 @@ details. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: These pair styles do not support mixing. Thus, coefficients for all diff --git a/doc/pair_resquared.html b/doc/pair_resquared.html index c5bd317a70..63e274fb52 100644 --- a/doc/pair_resquared.html +++ b/doc/pair_resquared.html @@ -13,6 +13,8 @@

    pair_style resquared/gpu command

    +

    pair_style resquared/omp command +

    Syntax:

    pair_style resquared cutoff 
    @@ -145,15 +147,15 @@ specified in the pair_style command is used.
     


    -

    Styles with a cuda, gpu, or opt suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in this section of the manual. +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues.

    -

    These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the Making LAMMPS section for more info.

    diff --git a/doc/pair_resquared.txt b/doc/pair_resquared.txt index 71d50e8ebe..0762b05224 100755 --- a/doc/pair_resquared.txt +++ b/doc/pair_resquared.txt @@ -8,6 +8,7 @@ pair_style resquared command :h3 pair_style resquared/gpu command :h3 +pair_style resquared/omp command :h3 [Syntax:] @@ -141,15 +142,15 @@ specified in the pair_style command is used. :line -Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same -as the corresponding style without the suffix. They have been -optimized to run faster, depending on your available hardware, as -discussed in "this section"_Section_accelerate.html of the manual. +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. -These accelerated styles are part of the USER-CUDA, GPU, and OPT -packages respectively. They are only enabled if LAMMPS was built with +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/pair_soft.html b/doc/pair_soft.html index a444b544ff..145056ece1 100644 --- a/doc/pair_soft.html +++ b/doc/pair_soft.html @@ -11,6 +11,8 @@

    pair_style soft command

    +

    pair_style soft/omp command +

    Syntax:

    pair_style soft cutoff 
    @@ -80,6 +82,28 @@ variables.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/pair_soft.txt b/doc/pair_soft.txt index d1ca823fe5..14f68d7c45 100644 --- a/doc/pair_soft.txt +++ b/doc/pair_soft.txt @@ -7,6 +7,7 @@ :line pair_style soft command :h3 +pair_style soft/omp command :h3 [Syntax:] @@ -77,6 +78,28 @@ variables. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/pair_sw.html b/doc/pair_sw.html index 6267d6ba2e..fe1fa3b116 100644 --- a/doc/pair_sw.html +++ b/doc/pair_sw.html @@ -11,6 +11,8 @@

    pair_style sw command

    +

    pair_style sw/omp command +

    Syntax:

    pair_style sw 
    @@ -137,6 +139,28 @@ taken from the ij and ik pairs (sigma, a, gamma)
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_sw.txt b/doc/pair_sw.txt index 1b62af869b..d1ea462f1b 100644 --- a/doc/pair_sw.txt +++ b/doc/pair_sw.txt @@ -7,6 +7,7 @@ :line pair_style sw command :h3 +pair_style sw/omp command :h3 [Syntax:] @@ -134,6 +135,28 @@ taken from the ij and ik pairs (sigma, a, gamma) :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_table.html b/doc/pair_table.html index 0d96816e54..6b59e441bc 100644 --- a/doc/pair_table.html +++ b/doc/pair_table.html @@ -11,6 +11,8 @@

    pair_style table command

    +

    pair_style table/omp command +

    Syntax:

    pair_style table style N 
    @@ -176,6 +178,28 @@ one that matches the specified keyword.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    This pair style does not support mixing. Thus, coefficients for all diff --git a/doc/pair_table.txt b/doc/pair_table.txt index a83961106a..64bdb31f46 100644 --- a/doc/pair_table.txt +++ b/doc/pair_table.txt @@ -7,6 +7,7 @@ :line pair_style table command :h3 +pair_style table/omp command :h3 [Syntax:] @@ -173,6 +174,28 @@ one that matches the specified keyword. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support mixing. Thus, coefficients for all diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html index ed15a307a1..96f629494a 100644 --- a/doc/pair_tersoff.html +++ b/doc/pair_tersoff.html @@ -15,6 +15,8 @@

    pair_style tersoff 
     
    +
    pair_style tersoff/omp 
    +

    Examples:

    pair_style tersoff
    @@ -158,6 +160,28 @@ defined in various papers.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt index f6cfd83169..2f0f539e95 100644 --- a/doc/pair_tersoff.txt +++ b/doc/pair_tersoff.txt @@ -11,6 +11,7 @@ pair_style tersoff command :h3 [Syntax:] pair_style tersoff :pre +pair_style tersoff/omp :pre [Examples:] @@ -155,6 +156,28 @@ defined in various papers. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_tersoff_zbl.html b/doc/pair_tersoff_zbl.html index 84e4c85fe5..be760ba0de 100644 --- a/doc/pair_tersoff_zbl.html +++ b/doc/pair_tersoff_zbl.html @@ -11,6 +11,8 @@

    pair_style tersoff/zbl command

    +

    pair_style tersoff/zbl/omp command +

    Syntax:

    pair_style tersoff/zbl 
    @@ -178,6 +180,28 @@ providing the base ZBL implementation.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_tersoff_zbl.txt b/doc/pair_tersoff_zbl.txt index ade09bd52d..bf69d712bf 100644 --- a/doc/pair_tersoff_zbl.txt +++ b/doc/pair_tersoff_zbl.txt @@ -7,6 +7,7 @@ :line pair_style tersoff/zbl command :h3 +pair_style tersoff/zbl/omp command :h3 [Syntax:] @@ -175,6 +176,28 @@ providing the base ZBL implementation. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to diff --git a/doc/pair_yukawa.html b/doc/pair_yukawa.html index 660dfdfd64..51cdc757c4 100644 --- a/doc/pair_yukawa.html +++ b/doc/pair_yukawa.html @@ -11,6 +11,8 @@

    pair_style yukawa command

    +

    pair_style yukawa/omp command +

    Syntax:

    pair_style yukawa kappa cutoff 
    @@ -46,6 +48,28 @@ cutoff is used.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/pair_yukawa.txt b/doc/pair_yukawa.txt index 6828af28ca..41b72a83a6 100644 --- a/doc/pair_yukawa.txt +++ b/doc/pair_yukawa.txt @@ -7,6 +7,7 @@ :line pair_style yukawa command :h3 +pair_style yukawa/omp command :h3 [Syntax:] @@ -43,6 +44,28 @@ cutoff is used. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/pair_yukawa_colloid.html b/doc/pair_yukawa_colloid.html index cdd706450d..fcb543318d 100644 --- a/doc/pair_yukawa_colloid.html +++ b/doc/pair_yukawa_colloid.html @@ -11,6 +11,8 @@

    pair_style yukawa/colloid command

    +

    pair_style yukawa/colloid/omp command +

    Syntax:

    pair_style yukawa/colloid kappa cutoff 
    @@ -77,6 +79,28 @@ yukawa/colloid cutoff is used.
     


    +

    Styles with a cuda, gpu, omp, or opt suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in this section of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. +

    +

    These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the Making LAMMPS +section for more info. +

    +

    You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the -suffix command-line +switch when you invoke LAMMPS, or you can +use the suffix command in your input script. +

    +

    See this section of the manual for more +instructions on how to use the accelerated styles effectively. +

    +
    +

    Mixing, shift, table, tail correction, restart, rRESPA info:

    For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/pair_yukawa_colloid.txt b/doc/pair_yukawa_colloid.txt index ee09adf696..fc85fe3dba 100644 --- a/doc/pair_yukawa_colloid.txt +++ b/doc/pair_yukawa_colloid.txt @@ -7,6 +7,7 @@ :line pair_style yukawa/colloid command :h3 +pair_style yukawa/colloid/omp command :h3 [Syntax:] @@ -74,6 +75,28 @@ yukawa/colloid cutoff is used. :line +Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally +the same as the corresponding style without the suffix. They have +been optimized to run faster, depending on your available hardware, +as discussed in "this section"_Section_accelerate.html of the manual. +The accelerated styles take the same arguments and should produce the +same results, except for round-off and precision issues. + +These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT +packages, respectively. They are only enabled if LAMMPS was built with +those packages. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +You can specify the accelerated styles explicitly in your input script +by including their suffix, or you can use the "-suffix command-line +switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can +use the "suffix"_suffix.html command in your input script. + +See "this section"_Section_accelerate.html of the manual for more +instructions on how to use the accelerated styles effectively. + +:line + [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, the A coefficient and cutoff diff --git a/doc/suffix.html b/doc/suffix.html index f60a581383..e58c86bf81 100644 --- a/doc/suffix.html +++ b/doc/suffix.html @@ -15,7 +15,7 @@

    suffix style 
     
    -
    • style = off or on or opt or gpu or cuda +
      • style = off or on or opt or omp or gpu or cuda

      Examples:

      @@ -30,24 +30,26 @@ exist. In that respect it operates the same as the this section of the manual. The "opt" style -corrsponds to the OPT package, the "gpu" style to the GPU package, and -the "cuda" style to the USER-CUDA package. +corrsponds to the OPT package, the "omp" style to the USER-OMP package, +the "gpu" style to the GPU package, and the "cuda" style to the +USER-CUDA package.

      These are the variants these packages provide:

      • OPT = a handful of pair styles, cache-optimized for faster CPU performance +
      • USER-OMP = a collection of pair, dihedral and fix styles with support for OpenMP multi-threading
      • GPU = a handful of pair styles and the PPPM kspace_style, optimized to run on one or more GPUs or multicore CPU/GPU nodes
      • USER-CUDA = a collection of atom, pair, fix, compute, and intergrate styles, optimized to run on one or more NVIDIA GPUs

      As an example, all of the packages provide a pair_style -lj/cut variant, with style names lj/cut/opt or -lj/cut/gpu or lj/cut/cuda. A variant styles can be specified +lj/cut variant, with style names lj/cut/opt, lj/cut/omp, +lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified explicitly in your input script, e.g. pair_style lj/cut/gpu. If the suffix command is used with the appropriate style, you do not need to -modify your input script. The specified suffix (opt,gpu,cuda) is +modify your input script. The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever your input script command creates a new atom, pair, fix, compute, or run style. If the variant diff --git a/doc/suffix.txt b/doc/suffix.txt index 758ce38e95..ec773f0eb7 100644 --- a/doc/suffix.txt +++ b/doc/suffix.txt @@ -12,7 +12,7 @@ suffix command :h3 suffix style :pre -style = {off} or {on} or {opt} or {gpu} or {cuda} :ul +style = {off} or {on} or {opt} or {omp} or {gpu} or {cuda} :ul [Examples:] @@ -27,24 +27,26 @@ exist. In that respect it operates the same as the "-suffix command-line switch"_Section_start.html#start_6. It also has options to turn off/on any suffix setting made via the command line. -The specified style can be {opt} or {gpu} or {cuda}. These refer to +The specified style can be {opt}, {omp}, {gpu}, or {cuda}. These refer to optional packages that LAMMPS can be built with, as described in "this section of the manual"_Section_start.html#start_3. The "opt" style -corrsponds to the OPT package, the "gpu" style to the GPU package, and -the "cuda" style to the USER-CUDA package. +corrsponds to the OPT package, the "omp" style to the USER-OMP package, +the "gpu" style to the GPU package, and the "cuda" style to the +USER-CUDA package. These are the variants these packages provide: OPT = a handful of pair styles, cache-optimized for faster CPU performance +USER-OMP = a collection of pair, dihedral and fix styles with support for OpenMP multi-threading GPU = a handful of pair styles and the PPPM kspace_style, optimized to run on one or more GPUs or multicore CPU/GPU nodes USER-CUDA = a collection of atom, pair, fix, compute, and intergrate styles, optimized to run on one or more NVIDIA GPUs :ul As an example, all of the packages provide a "pair_style -lj/cut"_pair_lj.html variant, with style names lj/cut/opt or -lj/cut/gpu or lj/cut/cuda. A variant styles can be specified +lj/cut"_pair_lj.html variant, with style names lj/cut/opt, lj/cut/omp, +lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified explicitly in your input script, e.g. pair_style lj/cut/gpu. If the suffix command is used with the appropriate style, you do not need to -modify your input script. The specified suffix (opt,gpu,cuda) is +modify your input script. The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever your input script command creates a new "atom"_atom_style.html, "pair"_pair_style.html, "fix"_fix.html, "compute"_compute.html, or "run"_run_style.html style. If the variant From 15203cb79244e335225756d084b8130880f27225 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 17:55:48 +0000 Subject: [PATCH 175/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7039 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/pair_gayberne.cpp | 2 - src/ASPHERE/pair_gayberne.h | 2 + src/ASPHERE/pair_resquared.cpp | 2 - src/ASPHERE/pair_resquared.h | 2 + src/CLASS2/dihedral_class2.h | 6 +- src/CLASS2/pair_lj_class2.h | 2 +- src/CLASS2/pair_lj_class2_coul_cut.h | 2 +- src/CLASS2/pair_lj_class2_coul_long.h | 2 +- src/COLLOID/pair_colloid.cpp | 2 - src/COLLOID/pair_colloid.h | 8 +- src/COLLOID/pair_lubricate.h | 4 +- src/COLLOID/pair_yukawa_colloid.h | 4 +- src/DIPOLE/pair_dipole_cut.h | 8 +- src/GRANULAR/fix_pour.h | 3 + src/GRANULAR/fix_wall_gran.cpp | 4 + src/GRANULAR/pair_gran_hertz_history.h | 2 +- src/GRANULAR/pair_gran_hooke.h | 2 +- src/GRANULAR/pair_gran_hooke_history.cpp | 4 +- src/GRANULAR/pair_gran_hooke_history.h | 3 +- src/KSPACE/pair_born_coul_long.h | 2 +- src/KSPACE/pair_lj_charmm_coul_long.h | 5 +- src/MANYBODY/fix_qeq_comb.h | 8 +- src/MANYBODY/pair_adp.h | 6 +- src/MANYBODY/pair_eam.h | 2 +- src/MANYBODY/pair_eim.h | 6 +- src/MANYBODY/pair_sw.h | 6 +- src/MOLECULE/angle_hybrid.cpp | 8 +- src/MOLECULE/dihedral_charmm.h | 6 +- src/MOLECULE/dihedral_harmonic.h | 6 +- src/MOLECULE/dihedral_helix.h | 6 +- src/MOLECULE/dihedral_hybrid.cpp | 11 +- src/MOLECULE/dihedral_multi_harmonic.h | 6 +- src/MOLECULE/dihedral_opls.h | 6 +- src/MOLECULE/improper_hybrid.cpp | 14 +- src/MOLECULE/pair_hbond_dreiding_morse.h | 4 +- .../pair_lj_charmm_coul_charmm_implicit.h | 2 +- src/PERI/fix_peri_neigh.cpp | 4 +- src/PERI/fix_peri_neigh.h | 2 + src/PERI/pair_peri_lps.cpp | 34 +-- src/PERI/pair_peri_lps.h | 4 +- src/PERI/pair_peri_pmb.cpp | 7 +- src/PERI/pair_peri_pmb.h | 6 +- src/USER-AWPMD/atom_vec_wavepacket.cpp | 4 +- src/USER-EFF/atom_vec_electron.cpp | 4 +- src/USER-MISC/dihedral_cosine_shift_exp.h | 6 +- src/USER-MISC/pair_cdeam.h | 30 +-- src/USER-MISC/pair_dipole_sf.h | 8 +- src/USER-MISC/pair_edip.cpp | 16 +- src/USER-MISC/pair_edip.h | 6 +- src/USER-MISC/pair_lj_sf.cpp | 8 +- src/USER-SPH/atom_vec_meso.cpp | 17 +- src/atom_vec_ellipsoid.cpp | 4 +- src/atom_vec_sphere.cpp | 4 +- src/bond_hybrid.cpp | 8 +- src/compute_pair.cpp | 15 +- src/fix_box_relax.cpp | 2 +- src/fix_gravity.h | 6 +- src/fix_nve_sphere.h | 8 +- src/fix_shear_history.h | 4 +- src/force.cpp | 194 ++++++++++++++---- src/force.h | 20 +- src/input.cpp | 8 +- src/pair.h | 1 + src/pair_born.h | 7 +- src/pair_buck.h | 2 +- src/pair_coul_debye.h | 4 +- src/pair_dpd_tstat.h | 2 +- src/pair_gauss.h | 6 +- src/pair_hybrid.cpp | 6 +- src/pair_lj96_cut.h | 5 +- src/pair_lj_cubic.h | 7 +- src/pair_lj_cut_coul_debye.h | 2 +- src/pair_lj_expand.h | 5 +- src/pair_lj_smooth.h | 2 +- src/pair_morse.h | 5 +- src/pair_soft.h | 7 +- src/pair_table.h | 8 +- src/set.cpp | 22 +- src/set.h | 2 +- src/variable.cpp | 19 +- src/variable.h | 3 +- 81 files changed, 432 insertions(+), 280 deletions(-) diff --git a/src/ASPHERE/pair_gayberne.cpp b/src/ASPHERE/pair_gayberne.cpp index 19dfdecde8..e3ad48491b 100755 --- a/src/ASPHERE/pair_gayberne.cpp +++ b/src/ASPHERE/pair_gayberne.cpp @@ -33,8 +33,6 @@ using namespace LAMMPS_NS; -enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; - /* ---------------------------------------------------------------------- */ PairGayBerne::PairGayBerne(LAMMPS *lmp) : Pair(lmp) diff --git a/src/ASPHERE/pair_gayberne.h b/src/ASPHERE/pair_gayberne.h index ea699061cb..0923d6112e 100755 --- a/src/ASPHERE/pair_gayberne.h +++ b/src/ASPHERE/pair_gayberne.h @@ -39,6 +39,8 @@ class PairGayBerne : public Pair { void read_restart_settings(FILE *); protected: + enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; + double cut_global; double **cut; diff --git a/src/ASPHERE/pair_resquared.cpp b/src/ASPHERE/pair_resquared.cpp index 20457226d5..13e57fa64e 100755 --- a/src/ASPHERE/pair_resquared.cpp +++ b/src/ASPHERE/pair_resquared.cpp @@ -33,8 +33,6 @@ using namespace LAMMPS_NS; -enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; - /* ---------------------------------------------------------------------- */ PairRESquared::PairRESquared(LAMMPS *lmp) : Pair(lmp), diff --git a/src/ASPHERE/pair_resquared.h b/src/ASPHERE/pair_resquared.h index c2146e18b2..dbc45ac0c9 100755 --- a/src/ASPHERE/pair_resquared.h +++ b/src/ASPHERE/pair_resquared.h @@ -39,6 +39,8 @@ class PairRESquared : public Pair { void read_restart_settings(FILE *); protected: + enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; + double cut_global; double **cut; diff --git a/src/CLASS2/dihedral_class2.h b/src/CLASS2/dihedral_class2.h index 09bf894405..c99258a627 100644 --- a/src/CLASS2/dihedral_class2.h +++ b/src/CLASS2/dihedral_class2.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralClass2 : public Dihedral { public: DihedralClass2(class LAMMPS *); - ~DihedralClass2(); - void compute(int, int); + virtual ~DihedralClass2(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k1,*k2,*k3; double *phi1,*phi2,*phi3; double *mbt_f1,*mbt_f2,*mbt_f3,*mbt_r0; diff --git a/src/CLASS2/pair_lj_class2.h b/src/CLASS2/pair_lj_class2.h index 764b8b8c92..6a24e51e91 100644 --- a/src/CLASS2/pair_lj_class2.h +++ b/src/CLASS2/pair_lj_class2.h @@ -28,7 +28,7 @@ class PairLJClass2 : public Pair { public: PairLJClass2(class LAMMPS *); virtual ~PairLJClass2(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/CLASS2/pair_lj_class2_coul_cut.h b/src/CLASS2/pair_lj_class2_coul_cut.h index 12fabc3f1a..1efa60a397 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.h +++ b/src/CLASS2/pair_lj_class2_coul_cut.h @@ -28,7 +28,7 @@ class PairLJClass2CoulCut : public Pair { public: PairLJClass2CoulCut(class LAMMPS *); virtual ~PairLJClass2CoulCut(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); diff --git a/src/CLASS2/pair_lj_class2_coul_long.h b/src/CLASS2/pair_lj_class2_coul_long.h index d1b19f84cf..ab903987bb 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.h +++ b/src/CLASS2/pair_lj_class2_coul_long.h @@ -28,7 +28,7 @@ class PairLJClass2CoulLong : public Pair { public: PairLJClass2CoulLong(class LAMMPS *); virtual ~PairLJClass2CoulLong(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); diff --git a/src/COLLOID/pair_colloid.cpp b/src/COLLOID/pair_colloid.cpp index 1965e98ac0..04211a3509 100644 --- a/src/COLLOID/pair_colloid.cpp +++ b/src/COLLOID/pair_colloid.cpp @@ -30,8 +30,6 @@ using namespace LAMMPS_NS; -enum{SMALL_SMALL,SMALL_LARGE,LARGE_LARGE}; - /* ---------------------------------------------------------------------- */ PairColloid::PairColloid(LAMMPS *lmp) : Pair(lmp) {} diff --git a/src/COLLOID/pair_colloid.h b/src/COLLOID/pair_colloid.h index 7b813aaf44..266fd9657b 100644 --- a/src/COLLOID/pair_colloid.h +++ b/src/COLLOID/pair_colloid.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairColloid : public Pair { public: PairColloid(class LAMMPS *); - ~PairColloid(); - void compute(int, int); + virtual ~PairColloid(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -38,7 +38,9 @@ class PairColloid : public Pair { void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); - private: + enum {SMALL_SMALL,SMALL_LARGE,LARGE_LARGE}; + + protected: double cut_global; double **cut; double **a12,**d1,**d2,**diameter,**a1,**a2,**offset; diff --git a/src/COLLOID/pair_lubricate.h b/src/COLLOID/pair_lubricate.h index 30c7bee63c..30c9f71baf 100644 --- a/src/COLLOID/pair_lubricate.h +++ b/src/COLLOID/pair_lubricate.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairLubricate : public Pair { public: PairLubricate(class LAMMPS *); - ~PairLubricate(); - void compute(int, int); + virtual ~PairLubricate(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/COLLOID/pair_yukawa_colloid.h b/src/COLLOID/pair_yukawa_colloid.h index 4e70c5233e..6db573a6a3 100644 --- a/src/COLLOID/pair_yukawa_colloid.h +++ b/src/COLLOID/pair_yukawa_colloid.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairYukawaColloid : public PairYukawa { public: PairYukawaColloid(class LAMMPS *); - ~PairYukawaColloid() {} - void compute(int, int); + virtual ~PairYukawaColloid() {} + virtual void compute(int, int); void init_style(); double init_one(int, int); double single(int, int, int, int, double, double, double, double &); diff --git a/src/DIPOLE/pair_dipole_cut.h b/src/DIPOLE/pair_dipole_cut.h index b69e845e2f..a828d6307b 100644 --- a/src/DIPOLE/pair_dipole_cut.h +++ b/src/DIPOLE/pair_dipole_cut.h @@ -26,9 +26,9 @@ namespace LAMMPS_NS { class PairDipoleCut : public Pair { public: - PairDipoleCut(class LAMMPS *); - ~PairDipoleCut(); - void compute(int, int); + PairDipoleCut(class LAMMPS *); + virtual ~PairDipoleCut(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); @@ -38,7 +38,7 @@ class PairDipoleCut : public Pair { void write_restart_settings(FILE *); void read_restart_settings(FILE *); - private: + protected: double cut_lj_global,cut_coul_global; double **cut_lj,**cut_ljsq; double **cut_coul,**cut_coulsq; diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h index d279f54046..ec9590b276 100644 --- a/src/GRANULAR/fix_pour.h +++ b/src/GRANULAR/fix_pour.h @@ -26,8 +26,11 @@ namespace LAMMPS_NS { class FixPour : public Fix { friend class PairGranHertzHistory; + friend class PairGranHertzHistoryOMP; friend class PairGranHooke; + friend class PairGranHookeOMP; friend class PairGranHookeHistory; + friend class PairGranHookeHistoryOMP; friend class PairGranHookeCuda; public: diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index a23f70c44d..0345274cb0 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -221,8 +221,12 @@ void FixWallGran::init() pairstyle = HOOKE; else if (force->pair_match("gran/hooke/history",1)) pairstyle = HOOKE_HISTORY; + else if (force->pair_match("gran/hooke/history/omp",1)) + pairstyle = HOOKE_HISTORY; else if (force->pair_match("gran/hertz/history",1)) pairstyle = HERTZ_HISTORY; + else if (force->pair_match("gran/hertz/history/omp",1)) + pairstyle = HERTZ_HISTORY; else error->all(FLERR,"Fix wall/gran is incompatible with Pair style"); } diff --git a/src/GRANULAR/pair_gran_hertz_history.h b/src/GRANULAR/pair_gran_hertz_history.h index 87a63fa57f..5c5877a161 100644 --- a/src/GRANULAR/pair_gran_hertz_history.h +++ b/src/GRANULAR/pair_gran_hertz_history.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairGranHertzHistory : public PairGranHookeHistory { public: PairGranHertzHistory(class LAMMPS *); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); }; diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/GRANULAR/pair_gran_hooke.h index 565a766f61..d5cff796f2 100644 --- a/src/GRANULAR/pair_gran_hooke.h +++ b/src/GRANULAR/pair_gran_hooke.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairGranHooke : public PairGranHookeHistory { public: PairGranHooke(class LAMMPS *); - void compute(int, int); + virtual void compute(int, int); }; } diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 6ab64ee371..847ed84a58 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -46,6 +46,7 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) no_virial_fdotr_compute = 1; history = 1; fix_history = NULL; + suffix = NULL; laststep = -1; } @@ -55,6 +56,7 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) PairGranHookeHistory::~PairGranHookeHistory() { if (fix_history) modify->delete_fix("SHEAR_HISTORY"); + if (suffix) delete[] suffix; if (allocated) { memory->destroy(setflag); @@ -393,7 +395,7 @@ void PairGranHookeHistory::init_style() fixarg[0] = (char *) "SHEAR_HISTORY"; fixarg[1] = (char *) "all"; fixarg[2] = (char *) "SHEAR_HISTORY"; - modify->add_fix(3,fixarg); + modify->add_fix(3,fixarg,suffix); delete [] fixarg; fix_history = (FixShearHistory *) modify->fix[modify->nfix-1]; fix_history->pair = this; diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h index 2bc2cf63cc..e645c12bfe 100644 --- a/src/GRANULAR/pair_gran_hooke_history.h +++ b/src/GRANULAR/pair_gran_hooke_history.h @@ -49,7 +49,8 @@ class PairGranHookeHistory : public Pair { bigint laststep; class FixShearHistory *fix_history; - int shearupdate; + + char *suffix; double *onerad_dynamic,*onerad_frozen; double *maxrad_dynamic,*maxrad_frozen; diff --git a/src/KSPACE/pair_born_coul_long.h b/src/KSPACE/pair_born_coul_long.h index 9cbeb9deb0..3a8c910dbd 100644 --- a/src/KSPACE/pair_born_coul_long.h +++ b/src/KSPACE/pair_born_coul_long.h @@ -28,7 +28,7 @@ class PairBornCoulLong : public Pair { public: PairBornCoulLong(class LAMMPS *); virtual ~PairBornCoulLong(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); diff --git a/src/KSPACE/pair_lj_charmm_coul_long.h b/src/KSPACE/pair_lj_charmm_coul_long.h index 4c3f0171cb..515d5d429a 100644 --- a/src/KSPACE/pair_lj_charmm_coul_long.h +++ b/src/KSPACE/pair_lj_charmm_coul_long.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairLJCharmmCoulLong : public Pair { public: PairLJCharmmCoulLong(class LAMMPS *); - ~PairLJCharmmCoulLong(); - void compute(int, int); + virtual ~PairLJCharmmCoulLong(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); diff --git a/src/MANYBODY/fix_qeq_comb.h b/src/MANYBODY/fix_qeq_comb.h index f8ddd0018a..48c7947f03 100644 --- a/src/MANYBODY/fix_qeq_comb.h +++ b/src/MANYBODY/fix_qeq_comb.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class FixQEQComb : public Fix { public: FixQEQComb(class LAMMPS *, int, char **); - ~FixQEQComb(); + virtual ~FixQEQComb(); int setmask(); - void init(); + virtual void init(); void setup(int); - void post_force(int); + virtual void post_force(int); void post_force_respa(int,int,int); double memory_usage(); - private: + protected: int me,firstflag; double precision; int nlevels_respa; diff --git a/src/MANYBODY/pair_adp.h b/src/MANYBODY/pair_adp.h index ee1d9af005..f50a3e4080 100644 --- a/src/MANYBODY/pair_adp.h +++ b/src/MANYBODY/pair_adp.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairADP : public Pair { public: PairADP(class LAMMPS *); - ~PairADP(); - void compute(int, int); + virtual ~PairADP(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); @@ -40,7 +40,7 @@ class PairADP : public Pair { void unpack_reverse_comm(int, int *, double *); double memory_usage(); - private: + protected: int nmax; // allocated size of per-atom arrays double cutforcesq,cutmax; diff --git a/src/MANYBODY/pair_eam.h b/src/MANYBODY/pair_eam.h index 4508cf4764..1b7b1f1f00 100644 --- a/src/MANYBODY/pair_eam.h +++ b/src/MANYBODY/pair_eam.h @@ -46,7 +46,7 @@ class PairEAM : public Pair { PairEAM(class LAMMPS *); virtual ~PairEAM(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); virtual void coeff(int, char **); void init_style(); diff --git a/src/MANYBODY/pair_eim.h b/src/MANYBODY/pair_eim.h index 22b89f2b98..cc4939c81c 100644 --- a/src/MANYBODY/pair_eim.h +++ b/src/MANYBODY/pair_eim.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class PairEIM : public Pair { public: PairEIM(class LAMMPS *); - ~PairEIM(); - void compute(int, int); + virtual ~PairEIM(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); @@ -41,7 +41,7 @@ class PairEIM : public Pair { void unpack_reverse_comm(int, int *, double *); double memory_usage(); - private: + protected: double **cutforcesq,cutmax; int nmax; double *rho,*fp; diff --git a/src/MANYBODY/pair_sw.h b/src/MANYBODY/pair_sw.h index 45053afc45..ddd23df169 100755 --- a/src/MANYBODY/pair_sw.h +++ b/src/MANYBODY/pair_sw.h @@ -27,14 +27,14 @@ namespace LAMMPS_NS { class PairSW : public Pair { public: PairSW(class LAMMPS *); - ~PairSW(); - void compute(int, int); + virtual ~PairSW(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); - private: + protected: struct Param { double epsilon,sigma; double littlea,lambda,gamma,costheta; diff --git a/src/MOLECULE/angle_hybrid.cpp b/src/MOLECULE/angle_hybrid.cpp index a71d87da17..869b2bf41a 100644 --- a/src/MOLECULE/angle_hybrid.cpp +++ b/src/MOLECULE/angle_hybrid.cpp @@ -207,8 +207,10 @@ void AngleHybrid::settings(int narg, char **arg) // one exception is 1st arg of style "table", which is non-numeric // need a better way to skip these exceptions + int dummy; nstyles = 0; i = 0; + while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) @@ -217,7 +219,7 @@ void AngleHybrid::settings(int narg, char **arg) error->all(FLERR,"Angle style hybrid cannot have hybrid as an argument"); if (strcmp(arg[i],"none") == 0) error->all(FLERR,"Angle style hybrid cannot have none as an argument"); - styles[nstyles] = force->new_angle(arg[i]); + styles[nstyles] = force->new_angle(arg[i],lmp->suffix,dummy); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); istyle = i; @@ -321,14 +323,14 @@ void AngleHybrid::read_restart(FILE *fp) allocate(); - int n; + int n,dummy; for (int m = 0; m < nstyles; m++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); keywords[m] = new char[n]; if (me == 0) fread(keywords[m],sizeof(char),n,fp); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_angle(keywords[m]); + styles[m] = force->new_angle(keywords[m],lmp->suffix,dummy); } } diff --git a/src/MOLECULE/dihedral_charmm.h b/src/MOLECULE/dihedral_charmm.h index f999ec2c22..f00a6e1a6d 100644 --- a/src/MOLECULE/dihedral_charmm.h +++ b/src/MOLECULE/dihedral_charmm.h @@ -28,14 +28,14 @@ namespace LAMMPS_NS { class DihedralCharmm : public Dihedral { public: DihedralCharmm(class LAMMPS *); - ~DihedralCharmm(); - void compute(int, int); + virtual ~DihedralCharmm(); + virtual void compute(int, int); void coeff(int, char **); void init_style(); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k,*weight,*cos_shift,*sin_shift; int *multiplicity,*shift; double **lj14_1,**lj14_2,**lj14_3,**lj14_4; diff --git a/src/MOLECULE/dihedral_harmonic.h b/src/MOLECULE/dihedral_harmonic.h index 959159d475..1645cf5017 100644 --- a/src/MOLECULE/dihedral_harmonic.h +++ b/src/MOLECULE/dihedral_harmonic.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralHarmonic : public Dihedral { public: DihedralHarmonic(class LAMMPS *); - ~DihedralHarmonic(); - void compute(int, int); + virtual ~DihedralHarmonic(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k,*cos_shift,*sin_shift; int *sign,*multiplicity; diff --git a/src/MOLECULE/dihedral_helix.h b/src/MOLECULE/dihedral_helix.h index f0bfabf1d8..a6a4261dae 100644 --- a/src/MOLECULE/dihedral_helix.h +++ b/src/MOLECULE/dihedral_helix.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralHelix : public Dihedral { public: DihedralHelix(class LAMMPS *); - ~DihedralHelix(); - void compute(int, int); + virtual ~DihedralHelix(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *aphi,*bphi,*cphi; void allocate(); diff --git a/src/MOLECULE/dihedral_hybrid.cpp b/src/MOLECULE/dihedral_hybrid.cpp index 4b416281d8..131762be28 100644 --- a/src/MOLECULE/dihedral_hybrid.cpp +++ b/src/MOLECULE/dihedral_hybrid.cpp @@ -165,16 +165,19 @@ void DihedralHybrid::settings(int narg, char **arg) styles = new Dihedral*[nstyles]; keywords = new char*[nstyles]; + int dummy; + for (int m = 0; m < nstyles; m++) { for (int i = 0; i < m; i++) if (strcmp(arg[m],arg[i]) == 0) error->all(FLERR,"Dihedral style hybrid cannot use " "same dihedral style twice"); if (strcmp(arg[m],"hybrid") == 0) - error->all(FLERR,"Dihedral style hybrid cannot have hybrid as an argument"); + error->all(FLERR, + "Dihedral style hybrid cannot have hybrid as an argument"); if (strcmp(arg[m],"none") == 0) error->all(FLERR,"Dihedral style hybrid cannot have none as an argument"); - styles[m] = force->new_dihedral(arg[m]); + styles[m] = force->new_dihedral(arg[m],lmp->suffix,dummy); keywords[m] = new char[strlen(arg[m])+1]; strcpy(keywords[m],arg[m]); } @@ -269,14 +272,14 @@ void DihedralHybrid::read_restart(FILE *fp) allocate(); - int n; + int n,dummy; for (int m = 0; m < nstyles; m++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); keywords[m] = new char[n]; if (me == 0) fread(keywords[m],sizeof(char),n,fp); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_dihedral(keywords[m]); + styles[m] = force->new_dihedral(keywords[m],lmp->suffix,dummy); } } diff --git a/src/MOLECULE/dihedral_multi_harmonic.h b/src/MOLECULE/dihedral_multi_harmonic.h index 851eda9cf4..da4d46fe71 100644 --- a/src/MOLECULE/dihedral_multi_harmonic.h +++ b/src/MOLECULE/dihedral_multi_harmonic.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralMultiHarmonic : public Dihedral { public: DihedralMultiHarmonic(class LAMMPS *); - ~DihedralMultiHarmonic(); - void compute(int, int); + virtual ~DihedralMultiHarmonic(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *a1,*a2,*a3,*a4,*a5; void allocate(); diff --git a/src/MOLECULE/dihedral_opls.h b/src/MOLECULE/dihedral_opls.h index ab3d5c1da0..772ae6e6b1 100644 --- a/src/MOLECULE/dihedral_opls.h +++ b/src/MOLECULE/dihedral_opls.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralOPLS : public Dihedral { public: DihedralOPLS(class LAMMPS *); - ~DihedralOPLS(); - void compute(int, int); + virtual ~DihedralOPLS(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k1,*k2,*k3,*k4; void allocate(); diff --git a/src/MOLECULE/improper_hybrid.cpp b/src/MOLECULE/improper_hybrid.cpp index 645913e841..898b3cd350 100644 --- a/src/MOLECULE/improper_hybrid.cpp +++ b/src/MOLECULE/improper_hybrid.cpp @@ -165,15 +165,19 @@ void ImproperHybrid::settings(int narg, char **arg) styles = new Improper*[nstyles]; keywords = new char*[nstyles]; + int dummy; + for (int m = 0; m < nstyles; m++) { for (int i = 0; i < m; i++) if (strcmp(arg[m],arg[i]) == 0) - error->all(FLERR,"Improper style hybrid cannot use same improper style twice"); + error->all(FLERR, + "Improper style hybrid cannot use same improper style twice"); if (strcmp(arg[m],"hybrid") == 0) - error->all(FLERR,"Improper style hybrid cannot have hybrid as an argument"); + error->all(FLERR, + "Improper style hybrid cannot have hybrid as an argument"); if (strcmp(arg[m],"none") == 0) error->all(FLERR,"Improper style hybrid cannot have none as an argument"); - styles[m] = force->new_improper(arg[m]); + styles[m] = force->new_improper(arg[m],lmp->suffix,dummy); keywords[m] = new char[strlen(arg[m])+1]; strcpy(keywords[m],arg[m]); } @@ -256,14 +260,14 @@ void ImproperHybrid::read_restart(FILE *fp) allocate(); - int n; + int n,dummy; for (int m = 0; m < nstyles; m++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); keywords[m] = new char[n]; if (me == 0) fread(keywords[m],sizeof(char),n,fp); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_improper(keywords[m]); + styles[m] = force->new_improper(keywords[m],lmp->suffix,dummy); } } diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.h b/src/MOLECULE/pair_hbond_dreiding_morse.h index d6fa5cb353..05eabb2e16 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.h +++ b/src/MOLECULE/pair_hbond_dreiding_morse.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairHbondDreidingMorse : public PairHbondDreidingLJ { public: PairHbondDreidingMorse(class LAMMPS *); - ~PairHbondDreidingMorse() {} - void compute(int, int); + virtual ~PairHbondDreidingMorse() {}; + virtual void compute(int, int); void coeff(int, char **); void init_style(); double single(int, int, int, int, double, double, double, double &); diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.h b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.h index 0b95f8fcdd..c5882a7495 100644 --- a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.h +++ b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairLJCharmmCoulCharmmImplicit : public PairLJCharmmCoulCharmm { public: PairLJCharmmCoulCharmmImplicit(class LAMMPS *); - void compute(int, int); + virtual void compute(int, int); double single(int, int, int, int, double, double, double, double &); }; diff --git a/src/PERI/fix_peri_neigh.cpp b/src/PERI/fix_peri_neigh.cpp index a6dbbcdfe5..eb7d8c8539 100644 --- a/src/PERI/fix_peri_neigh.cpp +++ b/src/PERI/fix_peri_neigh.cpp @@ -260,8 +260,8 @@ void FixPeriNeigh::setup(int vflag) double **x0 = atom->x0; double half_lc = 0.5*(domain->lattice->xlattice); double vfrac_scale; - PairPeriLPS *pairlps = dynamic_cast(anypair); - PairPeriPMB *pairpmb = dynamic_cast(anypair); + PairPeriLPS *pairlps = static_cast(anypair); + PairPeriPMB *pairpmb = static_cast(anypair); for (i = 0; i < nlocal; i++) { double xtmp0 = x0[i][0]; double ytmp0 = x0[i][1]; diff --git a/src/PERI/fix_peri_neigh.h b/src/PERI/fix_peri_neigh.h index 09ca455077..8a441f22cb 100644 --- a/src/PERI/fix_peri_neigh.h +++ b/src/PERI/fix_peri_neigh.h @@ -26,7 +26,9 @@ namespace LAMMPS_NS { class FixPeriNeigh : public Fix { friend class PairPeriPMB; + friend class PairPeriPMBOMP; friend class PairPeriLPS; + friend class PairPeriLPSOMP; friend class ComputeDamageAtom; public: diff --git a/src/PERI/pair_peri_lps.cpp b/src/PERI/pair_peri_lps.cpp index 4efd0b4f31..ab74710949 100644 --- a/src/PERI/pair_peri_lps.cpp +++ b/src/PERI/pair_peri_lps.cpp @@ -174,7 +174,7 @@ void PairPeriLPS::compute(int eflag, int vflag) double kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) / (3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]); - rk = (kshort * vfrac[j]) * (dr / sqrt(cutsq[itype][jtype])); + rk = (kshort * vfrac[j]) * (dr / cut[itype][jtype]); if (r > 0.0) fpair = -(rk/r); else fpair = 0.0; @@ -214,9 +214,9 @@ void PairPeriLPS::compute(int eflag, int vflag) comm->forward_comm_fix(modify->fix[ifix_peri]); // Volume-dependent part of the energy - for (i = 0; i < nlocal; i++) { - itype = type[i]; - if (eflag) { + if (eflag) { + for (i = 0; i < nlocal; i++) { + itype = type[i]; if (eflag_global) eng_vdwl += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]); if (eflag_atom) @@ -266,7 +266,7 @@ void PairPeriLPS::compute(int eflag, int vflag) delz0 = ztmp0 - x0[j][2]; if (periodic) domain->minimum_image(delx0,dely0,delz0); jtype = type[j]; - delta = sqrt(cutsq[itype][jtype]); + delta = cut[itype][jtype]; r = sqrt(rsq); dr = r - r0[i][jj]; @@ -316,8 +316,7 @@ void PairPeriLPS::compute(int eflag, int vflag) if (first) s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch); else - s0_new[i] = MAX(s0_new[i], - s00[itype][jtype] - (alpha[itype][jtype] * stretch)); + s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch)); first = false; } @@ -372,11 +371,11 @@ void PairPeriLPS::coeff(int narg, char **arg) force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); - double bulkmodulus_one = atof(arg[2]); - double shearmodulus_one = atof(arg[3]); - double cut_one = atof(arg[4]); - double s00_one = atof(arg[5]); - double alpha_one = atof(arg[6]); + double bulkmodulus_one = atof(arg[2]); + double shearmodulus_one = atof(arg[3]); + double cut_one = atof(arg[4]); + double s00_one = atof(arg[5]); + double alpha_one = atof(arg[6]); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -402,10 +401,11 @@ double PairPeriLPS::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - bulkmodulus[j][i] = bulkmodulus[i][j]; - shearmodulus[j][i] = shearmodulus[i][j]; - s00[j][i] = s00[i][j]; - alpha[j][i] = alpha[i][j]; + bulkmodulus[j][i] = bulkmodulus[i][j]; + shearmodulus[j][i] = shearmodulus[i][j]; + s00[j][i] = s00[i][j]; + alpha[j][i] = alpha[i][j]; + cut[j][i] = cut[i][j]; return cut[i][j]; } @@ -689,7 +689,7 @@ void PairPeriLPS::compute_dilatation() if (fabs(dr) < 2.2204e-016) dr = 0.0; jtype = type[j]; - delta = sqrt(cutsq[itype][jtype]); + delta = cut[itype][jtype]; // scale vfrac[j] if particle j near the horizon diff --git a/src/PERI/pair_peri_lps.h b/src/PERI/pair_peri_lps.h index 47ec71901e..602172ffa4 100644 --- a/src/PERI/pair_peri_lps.h +++ b/src/PERI/pair_peri_lps.h @@ -27,11 +27,11 @@ namespace LAMMPS_NS { class PairPeriLPS : public Pair { public: PairPeriLPS(class LAMMPS *); - ~PairPeriLPS(); + virtual ~PairPeriLPS(); int pack_comm(int, int *, double *, int, int *); void unpack_comm(int, int, double *); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/PERI/pair_peri_pmb.cpp b/src/PERI/pair_peri_pmb.cpp index c989de6afd..2d0ae40725 100644 --- a/src/PERI/pair_peri_pmb.cpp +++ b/src/PERI/pair_peri_pmb.cpp @@ -161,7 +161,7 @@ void PairPeriPMB::compute(int eflag, int vflag) dr = r - d_ij; rk = (15.0 * kspring[itype][jtype] * vfrac[j]) * - (dr / sqrt(cutsq[itype][jtype])); + (dr / cut[itype][jtype]); if (r > 0.0) fpair = -(rk/r); else fpair = 0.0; @@ -182,7 +182,7 @@ void PairPeriPMB::compute(int eflag, int vflag) // grow bond forces array if necessary - if (nlocal > nmax) { + if (atom->nmax > nmax) { memory->destroy(s0_new); nmax = atom->nmax; memory->create(s0_new,nmax,"pair:s0_new"); @@ -223,7 +223,7 @@ void PairPeriPMB::compute(int eflag, int vflag) if (periodic) domain->minimum_image(delx,dely,delz); rsq = delx*delx + dely*dely + delz*delz; jtype = type[j]; - delta = sqrt(cutsq[itype][jtype]); + delta = cut[itype][jtype]; r = sqrt(rsq); dr = r - r0[i][jj]; @@ -345,6 +345,7 @@ double PairPeriPMB::init_one(int i, int j) kspring[j][i] = kspring[i][j]; alpha[j][i] = alpha[i][j]; s00[j][i] = s00[i][j]; + cut[j][i] = cut[i][j]; return cut[i][j]; } diff --git a/src/PERI/pair_peri_pmb.h b/src/PERI/pair_peri_pmb.h index 6418b3013f..1065ba5233 100644 --- a/src/PERI/pair_peri_pmb.h +++ b/src/PERI/pair_peri_pmb.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairPeriPMB : public Pair { public: PairPeriPMB(class LAMMPS *); - ~PairPeriPMB(); - void compute(int, int); + virtual ~PairPeriPMB(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -38,7 +38,7 @@ class PairPeriPMB : public Pair { void write_restart_settings(FILE *) {} void read_restart_settings(FILE *) {} double single(int, int, int, int, double, double, double, double &); - double memory_usage(); + virtual double memory_usage(); protected: int ifix_peri; diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp index 5c9e789bf0..16cda89c52 100644 --- a/src/USER-AWPMD/atom_vec_wavepacket.cpp +++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp @@ -84,7 +84,7 @@ void AtomVecWavepacket::grow(int n) spin = memory->grow(atom->spin,nmax,"atom:spin"); eradius = memory->grow(atom->eradius,nmax,"atom:eradius"); ervel = memory->grow(atom->ervel,nmax,"atom:ervel"); - erforce = memory->grow(atom->erforce,nmax,"atom:erforce"); + erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"atom:erforce"); cs = memory->grow(atom->cs,2*nmax,"atom:cs"); csforce = memory->grow(atom->csforce,2*nmax,"atom:csforce"); @@ -997,7 +997,7 @@ bigint AtomVecWavepacket::memory_usage() if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax); if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax); - if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax); + if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads); if (atom->memcheck("ervelforce")) bytes += memory->usage(ervelforce,nmax); if (atom->memcheck("cs")) bytes += memory->usage(cs,2*nmax); diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp index 006de86019..4f73254c31 100644 --- a/src/USER-EFF/atom_vec_electron.cpp +++ b/src/USER-EFF/atom_vec_electron.cpp @@ -78,7 +78,7 @@ void AtomVecElectron::grow(int n) spin = memory->grow(atom->spin,nmax,"atom:spin"); eradius = memory->grow(atom->eradius,nmax,"atom:eradius"); ervel = memory->grow(atom->ervel,nmax,"atom:ervel"); - erforce = memory->grow(atom->erforce,nmax,"atom:erforce"); + erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"atom:erforce"); if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) @@ -845,7 +845,7 @@ bigint AtomVecElectron::memory_usage() if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax); if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax); - if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax); + if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads); return bytes; } diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.h b/src/USER-MISC/dihedral_cosine_shift_exp.h index 5691bff9ad..3e77bf4914 100644 --- a/src/USER-MISC/dihedral_cosine_shift_exp.h +++ b/src/USER-MISC/dihedral_cosine_shift_exp.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class DihedralCosineShiftExp : public Dihedral { public: DihedralCosineShiftExp(class LAMMPS *); - ~DihedralCosineShiftExp(); - void compute(int, int); + virtual ~DihedralCosineShiftExp(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: bool *doExpansion; double *umin,*a,*opt1; double *sint; diff --git a/src/USER-MISC/pair_cdeam.h b/src/USER-MISC/pair_cdeam.h index e39923d568..836ad2fe7c 100644 --- a/src/USER-MISC/pair_cdeam.h +++ b/src/USER-MISC/pair_cdeam.h @@ -35,7 +35,7 @@ public: virtual ~PairCDEAM(); /// Calculates the energies and forces for all atoms in the system. - void compute(int, int); + virtual void compute(int, int); /// Parses the pair_coeff command parameters for this pair style. void coeff(int, char **); @@ -62,7 +62,7 @@ public: v = (v + hcoeff[i]) * x; } return v + hcoeff[0]; - } + }; // Calculates the derivative of the h(x) polynomial. inline double evalHprime(double x) const { @@ -71,7 +71,7 @@ public: v = (v + (double)i * hcoeff[i]) * x; } return v + hcoeff[1]; - } + }; // We have two versions of the CD-EAM potential. The user can choose which one he wants to use: // @@ -124,7 +124,7 @@ public: index.p -= index.m; index.p = index.p <= 1.0 ? index.p : 1.0; return index; - } + }; // Converts a density value to an index value to be used in a spline table lookup. inline EAMTableIndex rhoToTableIndex(double rho) const { @@ -135,43 +135,43 @@ public: index.p -= index.m; index.p = index.p <= 1.0 ? index.p : 1.0; return index; - } + }; // Computes the derivative of rho(r) inline double RhoPrimeOfR(const EAMTableIndex& index, int itype, int jtype) const { const double* coeff = rhor_spline[type2rhor[itype][jtype]][index.m]; return (coeff[0]*index.p + coeff[1])*index.p + coeff[2]; - } + }; // Computes rho(r) inline double RhoOfR(const EAMTableIndex& index, int itype, int jtype) const { const double* coeff = rhor_spline[type2rhor[itype][jtype]][index.m]; return ((coeff[3]*index.p + coeff[4])*index.p + coeff[5])*index.p + coeff[6]; - } + }; // Computes the derivative of F(rho) inline double FPrimeOfRho(const EAMTableIndex& index, int itype) const { const double* coeff = frho_spline[type2frho[itype]][index.m]; return (coeff[0]*index.p + coeff[1])*index.p + coeff[2]; - } + }; // Computes F(rho) inline double FofRho(const EAMTableIndex& index, int itype) const { const double* coeff = frho_spline[type2frho[itype]][index.m]; return ((coeff[3]*index.p + coeff[4])*index.p + coeff[5])*index.p + coeff[6]; - } + }; // Computes the derivative of z2(r) inline double Z2PrimeOfR(const EAMTableIndex& index, int itype, int jtype) const { const double* coeff = z2r_spline[type2z2r[itype][jtype]][index.m]; return (coeff[0]*index.p + coeff[1])*index.p + coeff[2]; - } - + }; + // Computes z2(r) inline double Z2OfR(const EAMTableIndex& index, int itype, int jtype) const { const double* coeff = z2r_spline[type2z2r[itype][jtype]][index.m]; return ((coeff[3]*index.p + coeff[4])*index.p + coeff[5])*index.p + coeff[6]; - } + }; // Computes pair potential V_ij(r). inline double PhiOfR(const EAMTableIndex& index, int itype, int jtype, const double oneOverR) const { @@ -180,7 +180,7 @@ public: const double* coeff = z2r_spline[type2z2r[itype][jtype]][index.m]; const double z2 = ((coeff[3]*index.p + coeff[4])*index.p + coeff[5])*index.p + coeff[6]; return z2 * oneOverR; - } + }; // Computes pair potential V_ij(r) and its derivative. inline double PhiOfR(const EAMTableIndex& index, int itype, int jtype, const double oneOverR, double& phid) const { @@ -194,7 +194,7 @@ public: const double phi = z2 * oneOverR; phid = z2p * oneOverR - phi * oneOverR; return phi; - } + }; // Parameters @@ -224,7 +224,7 @@ public: PairCDEAM_TwoSite(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAM(lmp, 2) {} }; -}; +} #endif #endif diff --git a/src/USER-MISC/pair_dipole_sf.h b/src/USER-MISC/pair_dipole_sf.h index bed71801f4..945f48694c 100644 --- a/src/USER-MISC/pair_dipole_sf.h +++ b/src/USER-MISC/pair_dipole_sf.h @@ -26,9 +26,9 @@ namespace LAMMPS_NS { class PairDipoleSF : public Pair { public: - PairDipoleSF(class LAMMPS *); - ~PairDipoleSF(); - void compute(int, int); + PairDipoleSF(class LAMMPS *); + virtual ~PairDipoleSF(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); @@ -38,7 +38,7 @@ class PairDipoleSF : public Pair { void write_restart_settings(FILE *); void read_restart_settings(FILE *); - private: + protected: double cut_lj_global,cut_coul_global; double **cut_lj,**cut_ljsq; double **cut_coul,**cut_coulsq; diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp index 77e5ee20da..e949742dc7 100755 --- a/src/USER-MISC/pair_edip.cpp +++ b/src/USER-MISC/pair_edip.cpp @@ -554,15 +554,17 @@ void PairEDIP::allocateGrids(void) void PairEDIP::allocatePreLoops(void) { - memory->create(preInvR_ij,leadDimInteractionList,"edip:preInvR_ij"); - memory->create(preExp3B_ij,leadDimInteractionList,"edip:preExp3B_ij"); - memory->create(preExp3BDerived_ij,leadDimInteractionList, + int nthreads = comm->nthreads; + + memory->create(preInvR_ij,nthreads*leadDimInteractionList,"edip:preInvR_ij"); + memory->create(preExp3B_ij,nthreads*leadDimInteractionList,"edip:preExp3B_ij"); + memory->create(preExp3BDerived_ij,nthreads*leadDimInteractionList, "edip:preExp3BDerived_ij"); - memory->create(preExp2B_ij,leadDimInteractionList,"edip:preExp2B_ij"); - memory->create(preExp2BDerived_ij,leadDimInteractionList, + memory->create(preExp2B_ij,nthreads*leadDimInteractionList,"edip:preExp2B_ij"); + memory->create(preExp2BDerived_ij,nthreads*leadDimInteractionList, "edip:preExp2BDerived_ij"); - memory->create(prePow2B_ij,leadDimInteractionList,"edip:prePow2B_ij"); - memory->create(preForceCoord,5*leadDimInteractionList,"edip:preForceCoord"); + memory->create(prePow2B_ij,nthreads*leadDimInteractionList,"edip:prePow2B_ij"); + memory->create(preForceCoord,5*nthreads*leadDimInteractionList,"edip:preForceCoord"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-MISC/pair_edip.h b/src/USER-MISC/pair_edip.h index 4c86b5ea3f..d6cae99b48 100755 --- a/src/USER-MISC/pair_edip.h +++ b/src/USER-MISC/pair_edip.h @@ -27,14 +27,14 @@ namespace LAMMPS_NS { class PairEDIP : public Pair { public: PairEDIP(class LAMMPS *); - ~PairEDIP(); - void compute(int, int); + virtual ~PairEDIP(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); - private: + protected: struct Param { double A, B; double cutoffA, cutoffC, cutsq; diff --git a/src/USER-MISC/pair_lj_sf.cpp b/src/USER-MISC/pair_lj_sf.cpp index 633b8be2e8..9745f296be 100644 --- a/src/USER-MISC/pair_lj_sf.cpp +++ b/src/USER-MISC/pair_lj_sf.cpp @@ -92,12 +92,8 @@ void PairLJShiftedForce::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; - - if (j < nall) factor_lj = 1.0; - else { - factor_lj = special_lj[j/nall]; - j %= nall; - } + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp index b69686824c..792355007b 100644 --- a/src/USER-SPH/atom_vec_meso.cpp +++ b/src/USER-SPH/atom_vec_meso.cpp @@ -14,6 +14,7 @@ #include "stdlib.h" #include "atom_vec_meso.h" #include "atom.h" +#include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" @@ -68,12 +69,12 @@ void AtomVecMeso::grow(int n) { image = memory->grow(atom->image, nmax, "atom:image"); x = memory->grow(atom->x, nmax, 3, "atom:x"); v = memory->grow(atom->v, nmax, 3, "atom:v"); - f = memory->grow(atom->f, nmax, 3, "atom:f"); + f = memory->grow(atom->f, nmax*comm->nthreads, 3, "atom:f"); rho = memory->grow(atom->rho, nmax, "atom:rho"); - drho = memory->grow(atom->drho, nmax, "atom:drho"); + drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho"); e = memory->grow(atom->e, nmax, "atom:e"); - de = memory->grow(atom->de, nmax, "atom:de"); + de = memory->grow(atom->de, nmax*comm->nthreads, "atom:de"); vest = memory->grow(atom->vest, nmax, 3, "atom:vest"); cv = memory->grow(atom->cv, nmax, "atom:cv"); @@ -846,19 +847,19 @@ bigint AtomVecMeso::memory_usage() { if (atom->memcheck("image")) bytes += memory->usage(image, nmax); if (atom->memcheck("x")) - bytes += memory->usage(x, nmax); + bytes += memory->usage(x, nmax, 3); if (atom->memcheck("v")) - bytes += memory->usage(v, nmax); + bytes += memory->usage(v, nmax, 3); if (atom->memcheck("f")) - bytes += memory->usage(f, nmax); + bytes += memory->usage(f, nmax*comm->nthreads, 3); if (atom->memcheck("rho")) bytes += memory->usage(rho, nmax); if (atom->memcheck("drho")) - bytes += memory->usage(drho, nmax); + bytes += memory->usage(drho, nmax*comm->nthreads); if (atom->memcheck("e")) bytes += memory->usage(e, nmax); if (atom->memcheck("de")) - bytes += memory->usage(de, nmax); + bytes += memory->usage(de, nmax*comm->nthreads); if (atom->memcheck("cv")) bytes += memory->usage(cv, nmax); if (atom->memcheck("vest")) diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index d0cf4ce112..47c9ef97f6 100755 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -90,7 +90,7 @@ void AtomVecEllipsoid::grow(int n) rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); - torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); ellipsoid = memory->grow(atom->ellipsoid,nmax,"atom:ellipsoid"); if (atom->nextra_grow) @@ -1250,7 +1250,7 @@ bigint AtomVecEllipsoid::memory_usage() if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); - if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); if (atom->memcheck("ellipsoid")) bytes += memory->usage(ellipsoid,nmax); bytes += nmax_bonus*sizeof(Bonus); diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index babc914387..a3e2c34772 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -102,7 +102,7 @@ void AtomVecSphere::grow(int n) radius = memory->grow(atom->radius,nmax,"atom:radius"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); omega = memory->grow(atom->omega,nmax,3,"atom:omega"); - torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) @@ -1053,7 +1053,7 @@ bigint AtomVecSphere::memory_usage() if (atom->memcheck("radius")) bytes += memory->usage(radius,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); - if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); return bytes; } diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp index 435685d5ec..eb10d5f5b8 100644 --- a/src/bond_hybrid.cpp +++ b/src/bond_hybrid.cpp @@ -206,8 +206,10 @@ void BondHybrid::settings(int narg, char **arg) // one exception is 1st arg of style "table", which is non-numeric // need a better way to skip these exceptions + int dummy; nstyles = 0; i = 0; + while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) @@ -216,7 +218,7 @@ void BondHybrid::settings(int narg, char **arg) error->all(FLERR,"Bond style hybrid cannot have hybrid as an argument"); if (strcmp(arg[i],"none") == 0) error->all(FLERR,"Bond style hybrid cannot have none as an argument"); - styles[nstyles] = force->new_bond(arg[i]); + styles[nstyles] = force->new_bond(arg[i],lmp->suffix,dummy); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); istyle = i; @@ -319,14 +321,14 @@ void BondHybrid::read_restart(FILE *fp) allocate(); - int n; + int n,dummy; for (int m = 0; m < nstyles; m++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); keywords[m] = new char[n]; if (me == 0) fread(keywords[m],sizeof(char),n,fp); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_bond(keywords[m]); + styles[m] = force->new_bond(keywords[m],lmp->suffix,dummy); } } diff --git a/src/compute_pair.cpp b/src/compute_pair.cpp index e5e8dbda08..60c723b952 100644 --- a/src/compute_pair.cpp +++ b/src/compute_pair.cpp @@ -37,6 +37,7 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : timeflag = 1; int n = strlen(arg[3]) + 1; + if (lmp->suffix) n += strlen(lmp->suffix) + 1; pstyle = new char[n]; strcpy(pstyle,arg[3]); @@ -46,8 +47,17 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[4],"ecoul") == 0) evalue = ECOUL; } else evalue = EPAIR; + // check if pair style with and without suffix exists + pair = force->pair_match(pstyle,1); - if (!pair) error->all(FLERR,"Unrecognized pair style in compute pair command"); + if (!pair && lmp->suffix) { + strcat(pstyle,"/"); + strcat(pstyle,lmp->suffix); + pair = force->pair_match(pstyle,1); + } + + if (!pair) + error->all(FLERR,"Unrecognized pair style in compute pair command"); npair = pair->nextra; if (npair) { @@ -75,7 +85,8 @@ void ComputePair::init() // recheck for pair style in case it has been deleted pair = force->pair_match(pstyle,1); - if (!pair) error->all(FLERR,"Unrecognized pair style in compute pair command"); + if (!pair) + error->all(FLERR,"Unrecognized pair style in compute pair command"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_box_relax.cpp b/src/fix_box_relax.cpp index 09d6f28665..f2b045b511 100644 --- a/src/fix_box_relax.cpp +++ b/src/fix_box_relax.cpp @@ -901,7 +901,7 @@ void FixBoxRelax::compute_press_target() /* ---------------------------------------------------------------------- compute PV and strain energy for access to the user -/* ---------------------------------------------------------------------- */ + ---------------------------------------------------------------------- */ double FixBoxRelax::compute_scalar() { diff --git a/src/fix_gravity.h b/src/fix_gravity.h index 3f82d6c7f8..4b53c1b944 100644 --- a/src/fix_gravity.h +++ b/src/fix_gravity.h @@ -32,11 +32,11 @@ class FixGravity : public Fix { int setmask(); void init(); void setup(int); - void post_force(int); - void post_force_respa(int, int, int); + virtual void post_force(int); + virtual void post_force_respa(int, int, int); double compute_scalar(); - private: + protected: int style; double magnitude,dt; double phi,theta,phigrad,thetagrad; diff --git a/src/fix_nve_sphere.h b/src/fix_nve_sphere.h index 1582edc0e1..28fc47c591 100644 --- a/src/fix_nve_sphere.h +++ b/src/fix_nve_sphere.h @@ -27,13 +27,13 @@ namespace LAMMPS_NS { class FixNVESphere : public FixNVE { public: FixNVESphere(class LAMMPS *, int, char **); - ~FixNVESphere() {} + virtual ~FixNVESphere() {} int setmask(); void init(); - void initial_integrate(int); - void final_integrate(); + virtual void initial_integrate(int); + virtual void final_integrate(); - private: + protected: int extra; }; diff --git a/src/fix_shear_history.h b/src/fix_shear_history.h index 8bb3a9814f..cdf4f2cea4 100644 --- a/src/fix_shear_history.h +++ b/src/fix_shear_history.h @@ -35,7 +35,7 @@ class FixShearHistory : public Fix { int setmask(); void init(); void setup_pre_exchange(); - void pre_exchange(); + virtual void pre_exchange(); double memory_usage(); void grow_arrays(int); @@ -48,7 +48,7 @@ class FixShearHistory : public Fix { int size_restart(int); int maxsize_restart(); - private: + protected: int *npartner; // # of touching partners of each atom int **partner; // tags for the partners double ***shearpartner; // 3 shear values with the partner diff --git a/src/force.cpp b/src/force.cpp index 71511fc78f..67b3873309 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -112,7 +112,7 @@ void Force::init() create a pair style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_pair(const char *style, char *suffix) +void Force::create_pair(const char *style, const char *suffix) { delete [] pair_style; if (pair) delete pair; @@ -137,7 +137,7 @@ void Force::create_pair(const char *style, char *suffix) generate a pair class, first with suffix appended ------------------------------------------------------------------------- */ -Pair *Force::new_pair(const char *style, char *suffix, int &sflag) +Pair *Force::new_pair(const char *style, const char *suffix, int &sflag) { if (suffix && lmp->suffix_enable) { sflag = 1; @@ -185,20 +185,7 @@ Pair *Force::pair_match(const char *word, int exact) if (exact && strcmp(pair_style,word) == 0) return pair; else if (!exact && strstr(pair_style,word)) return pair; - else if (strcmp(pair_style,"hybrid") == 0) { - PairHybrid *hybrid = (PairHybrid *) pair; - count = 0; - for (int i = 0; i < hybrid->nstyles; i++) { - if (exact && strcmp(hybrid->keywords[i],word) == 0) - return hybrid->styles[i]; - if (!exact && strstr(hybrid->keywords[i],word)) { - iwhich = i; - count++; - } - } - if (!exact && count == 1) return hybrid->styles[iwhich]; - - } else if (strcmp(pair_style,"hybrid/overlay") == 0) { + else if (strstr(pair_style,"hybrid/overlay")) { PairHybridOverlay *hybrid = (PairHybridOverlay *) pair; count = 0; for (int i = 0; i < hybrid->nstyles; i++) { @@ -210,6 +197,19 @@ Pair *Force::pair_match(const char *word, int exact) } } if (!exact && count == 1) return hybrid->styles[iwhich]; + + } else if (strstr(pair_style,"hybrid")) { + PairHybrid *hybrid = (PairHybrid *) pair; + count = 0; + for (int i = 0; i < hybrid->nstyles; i++) { + if (exact && strcmp(hybrid->keywords[i],word) == 0) + return hybrid->styles[i]; + if (!exact && strstr(hybrid->keywords[i],word)) { + iwhich = i; + count++; + } + } + if (!exact && count == 1) return hybrid->styles[iwhich]; } return NULL; @@ -219,23 +219,50 @@ Pair *Force::pair_match(const char *word, int exact) create a bond style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_bond(const char *style) +void Force::create_bond(const char *style, const char *suffix) { delete [] bond_style; if (bond) delete bond; - bond = new_bond(style); - int n = strlen(style) + 1; - bond_style = new char[n]; - strcpy(bond_style,style); + int sflag; + bond = new_bond(style,suffix,sflag); + + if (sflag) { + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + int n = strlen(estyle) + 1; + bond_style = new char[n]; + strcpy(bond_style,estyle); + } else { + int n = strlen(style) + 1; + bond_style = new char[n]; + strcpy(bond_style,style); + } } /* ---------------------------------------------------------------------- - generate a bond class + generate a bond class, fist with suffix appended ------------------------------------------------------------------------- */ -Bond *Force::new_bond(const char *style) +Bond *Force::new_bond(const char *style, const char *suffix, int &sflag) { + if (suffix && lmp->suffix_enable) { + sflag = 1; + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + + if (0) return NULL; + +#define BOND_CLASS +#define BondStyle(key,Class) \ + else if (strcmp(estyle,#key) == 0) return new Class(lmp); +#include "style_bond.h" +#undef BondStyle +#undef BOND_CLASS + } + + sflag = 0; + if (strcmp(style,"none") == 0) return NULL; #define BOND_CLASS @@ -267,23 +294,51 @@ Bond *Force::bond_match(const char *style) create an angle style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_angle(const char *style) +void Force::create_angle(const char *style, const char *suffix) { delete [] angle_style; if (angle) delete angle; - angle = new_angle(style); - int n = strlen(style) + 1; - angle_style = new char[n]; - strcpy(angle_style,style); + int sflag; + angle = new_angle(style,suffix,sflag); + + if (sflag) { + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + int n = strlen(estyle) + 1; + angle_style = new char[n]; + strcpy(angle_style,estyle); + } else { + int n = strlen(style) + 1; + angle_style = new char[n]; + strcpy(angle_style,style); + } } /* ---------------------------------------------------------------------- generate an angle class ------------------------------------------------------------------------- */ -Angle *Force::new_angle(const char *style) +Angle *Force::new_angle(const char *style, const char *suffix, int &sflag) { + if (suffix && lmp->suffix_enable) { + sflag = 1; + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + + if (0) return NULL; + +#define ANGLE_CLASS +#define AngleStyle(key,Class) \ + else if (strcmp(estyle,#key) == 0) return new Class(lmp); +#include "style_angle.h" +#undef AngleStyle +#undef ANGLE_CLASS + + } + + sflag = 0; + if (strcmp(style,"none") == 0) return NULL; #define ANGLE_CLASS @@ -300,29 +355,58 @@ Angle *Force::new_angle(const char *style) create a dihedral style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_dihedral(const char *style) +void Force::create_dihedral(const char *style, const char *suffix) { delete [] dihedral_style; if (dihedral) delete dihedral; - dihedral = new_dihedral(style); - int n = strlen(style) + 1; - dihedral_style = new char[n]; - strcpy(dihedral_style,style); + int sflag; + dihedral = new_dihedral(style,suffix,sflag); + + if (sflag) { + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + int n = strlen(estyle) + 1; + dihedral_style = new char[n]; + strcpy(dihedral_style,estyle); + } else { + int n = strlen(style) + 1; + dihedral_style = new char[n]; + strcpy(dihedral_style,style); + } } /* ---------------------------------------------------------------------- generate a dihedral class ------------------------------------------------------------------------- */ -Dihedral *Force::new_dihedral(const char *style) +Dihedral *Force::new_dihedral(const char *style, const char *suffix, int &sflag) { + if (suffix && lmp->suffix_enable) { + sflag = 1; + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + + if (0) return NULL; + +#define DIHEDRAL_CLASS +#define DihedralStyle(key,Class) \ + else if (strcmp(estyle,#key) == 0) return new Class(lmp); +#include "style_dihedral.h" +#undef DihedralStyle +#undef DIHEDRAL_CLASS + + } + + sflag = 0; + if (strcmp(style,"none") == 0) return NULL; #define DIHEDRAL_CLASS #define DihedralStyle(key,Class) \ else if (strcmp(style,#key) == 0) return new Class(lmp); #include "style_dihedral.h" +#undef DihedralStyle #undef DIHEDRAL_CLASS else error->all(FLERR,"Invalid dihedral style"); @@ -333,23 +417,51 @@ Dihedral *Force::new_dihedral(const char *style) create an improper style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_improper(const char *style) +void Force::create_improper(const char *style, const char *suffix) { delete [] improper_style; if (improper) delete improper; - improper = new_improper(style); - int n = strlen(style) + 1; - improper_style = new char[n]; - strcpy(improper_style,style); + int sflag; + improper = new_improper(style,suffix,sflag); + + if (sflag) { + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + int n = strlen(estyle) + 1; + improper_style = new char[n]; + strcpy(improper_style,estyle); + } else { + int n = strlen(style) + 1; + improper_style = new char[n]; + strcpy(improper_style,style); + } } /* ---------------------------------------------------------------------- generate a improper class ------------------------------------------------------------------------- */ -Improper *Force::new_improper(const char *style) +Improper *Force::new_improper(const char *style, const char *suffix, int &sflag) { + if (suffix && lmp->suffix_enable) { + sflag = 1; + char estyle[256]; + sprintf(estyle,"%s/%s",style,suffix); + + if (0) return NULL; + +#define IMPROPER_CLASS +#define ImproperStyle(key,Class) \ + else if (strcmp(estyle,#key) == 0) return new Class(lmp); +#include "style_improper.h" +#undef ImproperStyle +#undef IMPROPER_CLASS + + } + + sflag = 0; + if (strcmp(style,"none") == 0) return NULL; #define IMPROPER_CLASS diff --git a/src/force.h b/src/force.h index fc1bd0a812..654b81a3a8 100644 --- a/src/force.h +++ b/src/force.h @@ -69,22 +69,22 @@ class Force : protected Pointers { ~Force(); void init(); - void create_pair(const char *, char *suffix = NULL); - class Pair *new_pair(const char *, char *, int &); + void create_pair(const char *, const char *suffix = NULL); + class Pair *new_pair(const char *, const char *, int &); class Pair *pair_match(const char *, int); - void create_bond(const char *); - class Bond *new_bond(const char *); + void create_bond(const char *, const char *suffix = NULL); + class Bond *new_bond(const char *, const char *, int &); class Bond *bond_match(const char *); - void create_angle(const char *); - class Angle *new_angle(const char *); + void create_angle(const char *, const char *suffix = NULL); + class Angle *new_angle(const char *, const char *, int &); - void create_dihedral(const char *); - class Dihedral *new_dihedral(const char *); + void create_dihedral(const char *, const char *suffix = NULL); + class Dihedral *new_dihedral(const char *, const char *, int &); - void create_improper(const char *); - class Improper *new_improper(const char *); + void create_improper(const char *, const char *suffix = NULL); + class Improper *new_improper(const char *, const char *, int &); void create_kspace(int, char **); diff --git a/src/input.cpp b/src/input.cpp index bcabc02303..ca4d450d72 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -834,7 +834,7 @@ void Input::angle_style() if (narg < 1) error->all(FLERR,"Illegal angle_style command"); if (atom->avec->angles_allow == 0) error->all(FLERR,"Angle_style command when no angles allowed"); - force->create_angle(arg[0]); + force->create_angle(arg[0],lmp->suffix); if (force->angle) force->angle->settings(narg-1,&arg[1]); } @@ -875,7 +875,7 @@ void Input::bond_style() if (narg < 1) error->all(FLERR,"Illegal bond_style command"); if (atom->avec->bonds_allow == 0) error->all(FLERR,"Bond_style command when no bonds allowed"); - force->create_bond(arg[0]); + force->create_bond(arg[0],lmp->suffix); if (force->bond) force->bond->settings(narg-1,&arg[1]); } @@ -937,7 +937,7 @@ void Input::dihedral_style() if (narg < 1) error->all(FLERR,"Illegal dihedral_style command"); if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Dihedral_style command when no dihedrals allowed"); - force->create_dihedral(arg[0]); + force->create_dihedral(arg[0],lmp->suffix); if (force->dihedral) force->dihedral->settings(narg-1,&arg[1]); } @@ -1014,7 +1014,7 @@ void Input::improper_style() if (narg < 1) error->all(FLERR,"Illegal improper_style command"); if (atom->avec->impropers_allow == 0) error->all(FLERR,"Improper_style command when no impropers allowed"); - force->create_improper(arg[0]); + force->create_improper(arg[0],lmp->suffix); if (force->improper) force->improper->settings(narg-1,&arg[1]); } diff --git a/src/pair.h b/src/pair.h index bc2045e179..7e396bbc50 100644 --- a/src/pair.h +++ b/src/pair.h @@ -21,6 +21,7 @@ namespace LAMMPS_NS { class Pair : protected Pointers { friend class BondQuartic; friend class DihedralCharmm; + friend class DihedralCharmmOMP; friend class FixGPU; friend class ThrOMP; diff --git a/src/pair_born.h b/src/pair_born.h index 20fe5db8cb..716392eb83 100644 --- a/src/pair_born.h +++ b/src/pair_born.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairBorn : public Pair { public: PairBorn(class LAMMPS *); - ~PairBorn(); - void compute(int, int); + virtual ~PairBorn(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -39,7 +40,7 @@ class PairBorn : public Pair { double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - private: + protected: double cut_global; double **cut; double **a,**rho,**sigma,**c, **d; diff --git a/src/pair_buck.h b/src/pair_buck.h index c9e13d6cfa..4e722eb41a 100644 --- a/src/pair_buck.h +++ b/src/pair_buck.h @@ -28,7 +28,7 @@ class PairBuck : public Pair { public: PairBuck(class LAMMPS *); virtual ~PairBuck(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/pair_coul_debye.h b/src/pair_coul_debye.h index 38e50af2f6..b3db256557 100644 --- a/src/pair_coul_debye.h +++ b/src/pair_coul_debye.h @@ -27,13 +27,13 @@ namespace LAMMPS_NS { class PairCoulDebye : public PairCoulCut { public: PairCoulDebye(class LAMMPS *); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void write_restart_settings(FILE *); void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); - private: + protected: double kappa; }; diff --git a/src/pair_dpd_tstat.h b/src/pair_dpd_tstat.h index f50ddcaa67..06f3ac0b8f 100644 --- a/src/pair_dpd_tstat.h +++ b/src/pair_dpd_tstat.h @@ -34,7 +34,7 @@ class PairDPDTstat : public PairDPD { void write_restart_settings(FILE *); void read_restart_settings(FILE *); - private: + protected: double t_start,t_stop; }; diff --git a/src/pair_gauss.h b/src/pair_gauss.h index c8e94a111b..795079273a 100644 --- a/src/pair_gauss.h +++ b/src/pair_gauss.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairGauss : public Pair { public: PairGauss(class LAMMPS *); - ~PairGauss(); - void compute(int,int); + virtual ~PairGauss(); + virtual void compute(int,int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -39,7 +39,7 @@ class PairGauss : public Pair { double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - private: + protected: double cut_global; double **cut; double **a,**b; diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 97939fef30..c23d694275 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -227,9 +227,9 @@ void PairHybrid::settings(int narg, char **arg) // need a better way to skip these exceptions int dummy; - nstyles = 0; i = 0; + while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) @@ -238,7 +238,7 @@ void PairHybrid::settings(int narg, char **arg) error->all(FLERR,"Pair style hybrid cannot have hybrid as an argument"); if (strcmp(arg[i],"none") == 0) error->all(FLERR,"Pair style hybrid cannot have none as an argument"); - styles[nstyles] = force->new_pair(arg[i],NULL,dummy); + styles[nstyles] = force->new_pair(arg[i],lmp->suffix,dummy); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); istyle = i; @@ -582,7 +582,7 @@ void PairHybrid::read_restart(FILE *fp) keywords[m] = new char[n]; 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],NULL,dummy); + styles[m] = force->new_pair(keywords[m],lmp->suffix,dummy); styles[m]->read_restart_settings(fp); } } diff --git a/src/pair_lj96_cut.h b/src/pair_lj96_cut.h index 0d65d8d0b2..1e9b94ae03 100644 --- a/src/pair_lj96_cut.h +++ b/src/pair_lj96_cut.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairLJ96Cut : public Pair { public: PairLJ96Cut(class LAMMPS *); - ~PairLJ96Cut(); - void compute(int, int); + virtual ~PairLJ96Cut(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); diff --git a/src/pair_lj_cubic.h b/src/pair_lj_cubic.h index 81caa3126f..9acf98a2ce 100644 --- a/src/pair_lj_cubic.h +++ b/src/pair_lj_cubic.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairLJCubic : public Pair { public: PairLJCubic(class LAMMPS *); - ~PairLJCubic(); - void compute(int, int); + virtual ~PairLJCubic(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -38,7 +39,7 @@ class PairLJCubic : public Pair { void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); - private: + protected: double **cut,**cut_inner,**cut_inner_sq; double **epsilon,**sigma; double **lj1,**lj2,**lj3,**lj4; diff --git a/src/pair_lj_cut_coul_debye.h b/src/pair_lj_cut_coul_debye.h index d008884801..4d10e89c12 100644 --- a/src/pair_lj_cut_coul_debye.h +++ b/src/pair_lj_cut_coul_debye.h @@ -28,7 +28,7 @@ class PairLJCutCoulDebye : public PairLJCutCoulCut { public: PairLJCutCoulDebye(class LAMMPS *); virtual ~PairLJCutCoulDebye() {} - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void write_restart_settings(FILE *); void read_restart_settings(FILE *); diff --git a/src/pair_lj_expand.h b/src/pair_lj_expand.h index 1d1b10c315..568827c3c1 100644 --- a/src/pair_lj_expand.h +++ b/src/pair_lj_expand.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairLJExpand : public Pair { public: PairLJExpand(class LAMMPS *); - ~PairLJExpand(); - void compute(int, int); + virtual ~PairLJExpand(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/pair_lj_smooth.h b/src/pair_lj_smooth.h index 6b2fc150bb..ecc67dd527 100644 --- a/src/pair_lj_smooth.h +++ b/src/pair_lj_smooth.h @@ -28,7 +28,7 @@ class PairLJSmooth : public Pair { public: PairLJSmooth(class LAMMPS *); virtual ~PairLJSmooth(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/pair_morse.h b/src/pair_morse.h index aca12aecc3..a6c628d3f0 100644 --- a/src/pair_morse.h +++ b/src/pair_morse.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairMorse : public Pair { public: PairMorse(class LAMMPS *); - ~PairMorse(); - void compute(int, int); + virtual ~PairMorse(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/pair_soft.h b/src/pair_soft.h index fbfd3ca43d..1558f899bc 100644 --- a/src/pair_soft.h +++ b/src/pair_soft.h @@ -29,8 +29,9 @@ class PairSoft : public Pair { public: PairSoft(class LAMMPS *); - ~PairSoft(); - void compute(int, int); + virtual ~PairSoft(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -41,7 +42,7 @@ class PairSoft : public Pair { double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - private: + protected: double PI; double cut_global; double **prefactor; diff --git a/src/pair_table.h b/src/pair_table.h index f98746e0c9..3ef6466261 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -27,8 +27,9 @@ namespace LAMMPS_NS { class PairTable : public Pair { public: PairTable(class LAMMPS *); - ~PairTable(); - void compute(int, int); + virtual ~PairTable(); + + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); @@ -39,8 +40,9 @@ class PairTable : public Pair { double single(int, int, int, int, double, double, double, double &); void *extract(char *, int &); - private: + protected: int tabstyle,tablength; + enum {LOOKUP=0, LINEAR=1, SPLINE=2, BITMAP=3}; struct Table { int ninput,rflag,fpflag,match,ntablebits; int nshiftbits,nmask; diff --git a/src/set.cpp b/src/set.cpp index be3cd5867d..507fa812f5 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -30,7 +30,10 @@ #include "math_extra.h" #include "error.h" +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT}; enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE, @@ -42,13 +45,6 @@ enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE, /* ---------------------------------------------------------------------- */ -Set::Set(LAMMPS *lmp) : Pointers(lmp) -{ - PI = 4.0*atan(1.0); -} - -/* ---------------------------------------------------------------------- */ - void Set::command(int narg, char **arg) { if (domain->box_exist == 0) @@ -415,11 +411,11 @@ void Set::set(int keyword) else if (keyword == DENSITY) { if (atom->radius_flag && atom->radius[i] > 0.0) - atom->rmass[i] = 4.0*PI/3.0 * + atom->rmass[i] = 4.0*MY_PI*THIRD * atom->radius[i]*atom->radius[i]*atom->radius[i] * dvalue; else if (atom->ellipsoid_flag && atom->ellipsoid[i] >= 0) { double *shape = avec_ellipsoid->bonus[atom->ellipsoid[i]].shape; - atom->rmass[i] = 4.0*PI/3.0 * shape[0]*shape[1]*shape[2] * dvalue; + atom->rmass[i] = 4.0*MY_PI*THIRD * shape[0]*shape[1]*shape[2] * dvalue; } else atom->rmass[i] = dvalue; // reset any or all of 3 image flags @@ -450,7 +446,7 @@ void Set::set(int keyword) if (atom->ellipsoid[i] < 0) error->one(FLERR,"Cannot set quaternion for atom that is not an ellipsoid"); double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; - double theta2 = 0.5 * PI * wvalue/180.0; + double theta2 = MY_PI2 * wvalue/180.0; double sintheta2 = sin(theta2); quat[0] = cos(theta2); quat[1] = xvalue * sintheta2; @@ -554,8 +550,8 @@ void Set::setrandom(int keyword) s = random->uniform(); t1 = sqrt(1.0-s); t2 = sqrt(s); - theta1 = 2.0*PI*random->uniform(); - theta2 = 2.0*PI*random->uniform(); + theta1 = 2.0*MY_PI*random->uniform(); + theta2 = 2.0*MY_PI*random->uniform(); quat[0] = cos(theta2)*t2; quat[1] = sin(theta1)*t1; quat[2] = cos(theta1)*t1; @@ -572,7 +568,7 @@ void Set::setrandom(int keyword) "that is not an ellipsoid"); quat = bonus[ellipsoid[i]].quat; random->reset(seed,x[i]); - theta2 = PI*random->uniform(); + theta2 = MY_PI*random->uniform(); quat[0] = cos(theta2); quat[1] = 0.0; quat[2] = 0.0; diff --git a/src/set.h b/src/set.h index b49040f8ec..5e1fd4e8c7 100644 --- a/src/set.h +++ b/src/set.h @@ -26,7 +26,7 @@ namespace LAMMPS_NS { class Set : protected Pointers { public: - Set(class LAMMPS *); + Set(class LAMMPS *lmp) : Pointers(lmp) {}; void command(int, char **); private: diff --git a/src/variable.cpp b/src/variable.cpp index a884455137..c6f955f75e 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -32,7 +32,10 @@ #include "memory.h" #include "error.h" +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; #define VARDELTA 4 #define MAXLEVEL 4 @@ -88,8 +91,6 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp) precedence[MULTIPLY] = precedence[DIVIDE] = 6; precedence[CARAT] = 7; precedence[UNARY] = precedence[NOT] = 8; - - PI = 4.0*atan(1.0); } /* ---------------------------------------------------------------------- */ @@ -1767,7 +1768,7 @@ double Variable::collapse_tree(Tree *tree) tree->type = VALUE; if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/arg3; + double omega = 2.0*MY_PI/arg3; tree->value = arg1 + arg2*sin(omega*delta*update->dt); return tree->value; } @@ -1781,7 +1782,7 @@ double Variable::collapse_tree(Tree *tree) tree->type = VALUE; if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/arg3; + double omega = 2.0*MY_PI/arg3; tree->value = arg1 + arg2*(1.0-cos(omega*delta*update->dt)); return tree->value; } @@ -1997,7 +1998,7 @@ double Variable::eval_tree(Tree *tree, int i) arg3 = eval_tree(tree->right,i); if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/arg3; + double omega = 2.0*MY_PI/arg3; arg = arg1 + arg2*sin(omega*delta*update->dt); return arg; } @@ -2008,7 +2009,7 @@ double Variable::eval_tree(Tree *tree, int i) arg3 = eval_tree(tree->right,i); if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/arg3; + double omega = 2.0*MY_PI/arg3; arg = arg1 + arg2*(1.0-cos(omega*delta*update->dt)); return arg; } @@ -2385,7 +2386,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, if (value3 == 0.0) error->all(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/value3; + double omega = 2.0*MY_PI/value3; double value = value1 + value2*sin(omega*delta*update->dt); argstack[nargstack++] = value; } @@ -2399,7 +2400,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, if (value3 == 0.0) error->all(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; - double omega = 2.0*PI/value3; + double omega = 2.0*MY_PI/value3; double value = value1 + value2*(1.0-cos(omega*delta*update->dt)); argstack[nargstack++] = value; } @@ -3058,7 +3059,7 @@ int Variable::is_constant(char *word) double Variable::constant(char *word) { - if (strcmp(word,"PI") == 0) return PI; + if (strcmp(word,"PI") == 0) return MY_PI; return 0.0; } diff --git a/src/variable.h b/src/variable.h index 3d2c75e027..aa8ef616fe 100644 --- a/src/variable.h +++ b/src/variable.h @@ -35,7 +35,6 @@ class Variable : protected Pointers { double evaluate_boolean(char *); private: - int me; int nvar; // # of defined variables int maxvar; // max # of variables arrays can hold char **names; // name of each variable @@ -44,13 +43,13 @@ class Variable : protected Pointers { int *which; // next available value for each variable int *pad; // 1 = pad loop/uloop variables with 0s, 0 = no pad char ***data; // str value of each variable's values - double PI; class RanMars *randomequal; // random number generator for equal-style vars class RanMars *randomatom; // random number generator for atom-style vars int precedence[16]; // precedence level of math operators // set length to include OR in enum + int me; struct Tree { // parse tree for atom-style variables double value; From 0974524f0f9c1de6f99582b7efd3944610f69d56 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 17:55:56 +0000 Subject: [PATCH 176/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7040 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/math_const.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/math_const.h diff --git a/src/math_const.h b/src/math_const.h new file mode 100644 index 0000000000..cf7e8a6112 --- /dev/null +++ b/src/math_const.h @@ -0,0 +1,29 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifndef LMP_MATH_CONST_H +#define LMP_MATH_CONST_H + +namespace LAMMPS_NS { + +namespace MathConst { + static const double THIRD = 1.0/3.0; + static const double MY_PI = 3.14159265358979323846; // pi + static const double MY_PI2 = 1.57079632679489661923; // pi/2 + static const double MY_PI4 = 0.78539816339744830962; // pi/4 + static const double MY_PIS = 1.77245385090551602729; // sqrt(pi) +} + +} + +#endif From 649c0c437c721f9c788182e3ce964498947e193d Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 18:04:03 +0000 Subject: [PATCH 177/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7041 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 28 ++-------------------------- doc/Section_commands.txt | 19 ------------------- doc/angle_hybrid.html | 28 ---------------------------- doc/angle_hybrid.txt | 27 --------------------------- doc/bond_hybrid.html | 28 ---------------------------- doc/bond_hybrid.txt | 27 --------------------------- doc/dihedral_hybrid.html | 28 ---------------------------- doc/dihedral_hybrid.txt | 27 --------------------------- doc/improper_hybrid.html | 28 ---------------------------- doc/improper_hybrid.txt | 27 --------------------------- 10 files changed, 2 insertions(+), 265 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 92b37781ee..839ca37981 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -498,14 +498,6 @@ package. harmonic/shiftharmonic/shift/cut -

      These are accelerated bond styles, which can be used if LAMMPS is -built with the appropriate accelerated -package. -

      - -

      Angle_style potentials @@ -527,14 +519,6 @@ package. cg/cmmcosine/shiftcosine/shift/exp -

      These are accelerated angle styles, which can be used if LAMMPS is -built with the appropriate accelerated -package. -

      - -

      Dihedral_style potentials @@ -561,8 +545,8 @@ built with the appropriate accelerated package.


      @@ -578,14 +562,6 @@ description: harmonicumbrella -

      These are accelerated improper styles, which can be used if LAMMPS is -built with the appropriate accelerated -package. -

      - -

      Kspace solvers diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 3fdae72257..d6e2e5dd17 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -835,12 +835,6 @@ package"_Section_start.html#start_3. "harmonic/shift"_bond_harmonic_shift.html, "harmonic/shift/cut"_bond_harmonic_shift_cut.html :tb(c=4,ea=c) -These are accelerated bond styles, which can be used if LAMMPS is -built with the "appropriate accelerated -package"_Section_accelerate.html. - -"hybrid/omp"_bond_hybrid.html :tb(c=4,ea=c) - :line Angle_style potentials :h4 @@ -867,12 +861,6 @@ package"_Section_start.html#start_3. "cosine/shift"_angle_cosine_shift.html, "cosine/shift/exp"_angle_cosine_shift_exp.html :tb(c=4,ea=c) -These are accelerated angle styles, which can be used if LAMMPS is -built with the "appropriate accelerated -package"_Section_accelerate.html. - -"hybrid/omp"_angle_hybrid.html :tb(c=4,ea=c) - :line Dihedral_style potentials :h4 @@ -900,7 +888,6 @@ These are accelerated dihedral styles, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. -"hybrid/omp"_dihedral_hybrid.html, "charmm/omp"_dihedral_charmm.html, "class2/omp"_dihedral_class2.html, "cosine/shift/exp/omp"_dihedral_cosine_shift_exp.html, @@ -924,12 +911,6 @@ description: "harmonic"_improper_harmonic.html, "umbrella"_improper_umbrella.html :tb(c=4,ea=c,w=100) -These are accelerated improper styles, which can be used if LAMMPS is -built with the "appropriate accelerated -package"_Section_accelerate.html. - -"hybrid/omp"_improper_hybrid.html :tb(c=4,ea=c,w=100) - :line Kspace solvers :h4 diff --git a/doc/angle_hybrid.html b/doc/angle_hybrid.html index a9cd04b369..9a4571a11e 100644 --- a/doc/angle_hybrid.html +++ b/doc/angle_hybrid.html @@ -11,8 +11,6 @@

      angle_style hybrid command

      -

      angle_style hybrid/omp command -

      Syntax:

      angle_style hybrid style1 style2 ... 
      @@ -78,32 +76,6 @@ for specific angle types.
       


      -

      Styles with a cuda, gpu, omp, or opt suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in this section of the manual. -

      -

      Since the hybrid style delegates computation to the individual -sub-styles, the suffix versions of the hybrid styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. -

      -

      The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -Making LAMMPS section for more info. -

      -

      You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the -suffix command-line -switch when you invoke LAMMPS, or you can -use the suffix command in your input script. -

      -

      See this section of the manual for more -instructions on how to use the accelerated styles effectively. -

      -
      -

      Restrictions:

      This angle style can only be used if LAMMPS was built with the diff --git a/doc/angle_hybrid.txt b/doc/angle_hybrid.txt index 6662216b4c..4f500a0700 100644 --- a/doc/angle_hybrid.txt +++ b/doc/angle_hybrid.txt @@ -7,7 +7,6 @@ :line angle_style hybrid command :h3 -angle_style hybrid/omp command :h3 [Syntax:] @@ -74,32 +73,6 @@ for specific angle types. :line -Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in "this section"_Section_accelerate.html of the manual. - -Since the {hybrid} style delegates computation to the individual -sub-styles, the suffix versions of the {hybrid} styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. - -The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -"Making LAMMPS"_Section_start.html#start_3 section for more info. - -You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the "-suffix command-line -switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can -use the "suffix"_suffix.html command in your input script. - -See "this section"_Section_accelerate.html of the manual for more -instructions on how to use the accelerated styles effectively. - -:line - [Restrictions:] This angle style can only be used if LAMMPS was built with the diff --git a/doc/bond_hybrid.html b/doc/bond_hybrid.html index fc1a85093f..1d1926434f 100644 --- a/doc/bond_hybrid.html +++ b/doc/bond_hybrid.html @@ -11,8 +11,6 @@

      bond_style hybrid command

      -

      bond_style hybrid/omp command -

      Syntax:

      bond_style hybrid style1 style2 ... 
      @@ -61,32 +59,6 @@ bond types.
       


      -

      Styles with a cuda, gpu, omp, or opt suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in this section of the manual. -

      -

      Since the hybrid style delegates computation to the individual -sub-styles, the suffix versions of the hybrid styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. -

      -

      The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -Making LAMMPS section for more info. -

      -

      You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the -suffix command-line -switch when you invoke LAMMPS, or you can -use the suffix command in your input script. -

      -

      See this section of the manual for more -instructions on how to use the accelerated styles effectively. -

      -
      -

      Restrictions:

      This bond style can only be used if LAMMPS was built with the diff --git a/doc/bond_hybrid.txt b/doc/bond_hybrid.txt index 683e5cd73f..ec3053a83f 100644 --- a/doc/bond_hybrid.txt +++ b/doc/bond_hybrid.txt @@ -7,7 +7,6 @@ :line bond_style hybrid command :h3 -bond_style hybrid/omp command :h3 [Syntax:] @@ -57,32 +56,6 @@ bond types. :line -Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in "this section"_Section_accelerate.html of the manual. - -Since the {hybrid} style delegates computation to the individual -sub-styles, the suffix versions of the {hybrid} styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. - -The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -"Making LAMMPS"_Section_start.html#start_3 section for more info. - -You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the "-suffix command-line -switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can -use the "suffix"_suffix.html command in your input script. - -See "this section"_Section_accelerate.html of the manual for more -instructions on how to use the accelerated styles effectively. - -:line - [Restrictions:] This bond style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_hybrid.html b/doc/dihedral_hybrid.html index 4bee37a9e2..69bbe932df 100644 --- a/doc/dihedral_hybrid.html +++ b/doc/dihedral_hybrid.html @@ -11,8 +11,6 @@

      dihedral_style hybrid command

      -

      dihedral_style hybrid/omp command -

      Syntax:

      dihedral_style hybrid style1 style2 ... 
      @@ -79,32 +77,6 @@ for specific dihedral types.
       


      -

      Styles with a cuda, gpu, omp, or opt suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in this section of the manual. -

      -

      Since the hybrid style delegates computation to the individual -sub-styles, the suffix versions of the hybrid styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. -

      -

      The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -Making LAMMPS section for more info. -

      -

      You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the -suffix command-line -switch when you invoke LAMMPS, or you can -use the suffix command in your input script. -

      -

      See this section of the manual for more -instructions on how to use the accelerated styles effectively. -

      -
      -

      Restrictions:

      This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/dihedral_hybrid.txt b/doc/dihedral_hybrid.txt index 6a64359db1..6b00a2f025 100644 --- a/doc/dihedral_hybrid.txt +++ b/doc/dihedral_hybrid.txt @@ -7,7 +7,6 @@ :line dihedral_style hybrid command :h3 -dihedral_style hybrid/omp command :h3 [Syntax:] @@ -75,32 +74,6 @@ for specific dihedral types. :line -Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in "this section"_Section_accelerate.html of the manual. - -Since the {hybrid} style delegates computation to the individual -sub-styles, the suffix versions of the {hybrid} styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. - -The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -"Making LAMMPS"_Section_start.html#start_3 section for more info. - -You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the "-suffix command-line -switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can -use the "suffix"_suffix.html command in your input script. - -See "this section"_Section_accelerate.html of the manual for more -instructions on how to use the accelerated styles effectively. - -:line - [Restrictions:] This dihedral style can only be used if LAMMPS was built with the diff --git a/doc/improper_hybrid.html b/doc/improper_hybrid.html index e00479867f..3bbdf3710d 100644 --- a/doc/improper_hybrid.html +++ b/doc/improper_hybrid.html @@ -11,8 +11,6 @@

      improper_style hybrid command

      -

      improper_style hybrid/omp command -

      Syntax:

      improper_style hybrid style1 style2 ... 
      @@ -57,32 +55,6 @@ types.
       


      -

      Styles with a cuda, gpu, omp, or opt suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in this section of the manual. -

      -

      Since the hybrid style delegates computation to the individual -sub-styles, the suffix versions of the hybrid styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. -

      -

      The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -Making LAMMPS section for more info. -

      -

      You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the -suffix command-line -switch when you invoke LAMMPS, or you can -use the suffix command in your input script. -

      -

      See this section of the manual for more -instructions on how to use the accelerated styles effectively. -

      -
      -

      Restrictions:

      This improper style can only be used if LAMMPS was built with the diff --git a/doc/improper_hybrid.txt b/doc/improper_hybrid.txt index 77d62b2e64..620b381717 100644 --- a/doc/improper_hybrid.txt +++ b/doc/improper_hybrid.txt @@ -7,7 +7,6 @@ :line improper_style hybrid command :h3 -improper_style hybrid/omp command :h3 [Syntax:] @@ -53,32 +52,6 @@ types. :line -Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in "this section"_Section_accelerate.html of the manual. - -Since the {hybrid} style delegates computation to the individual -sub-styles, the suffix versions of the {hybrid} styles are used -to propagate the corresponding suffix to all sub-styles, if those -accelerated versions exist. Otherwise the non-accelerated version -will be used. - -The individual accelerated sub-styles are part of the USER-CUDA, GPU, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the -"Making LAMMPS"_Section_start.html#start_3 section for more info. - -You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the "-suffix command-line -switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can -use the "suffix"_suffix.html command in your input script. - -See "this section"_Section_accelerate.html of the manual for more -instructions on how to use the accelerated styles effectively. - -:line - [Restrictions:] This improper style can only be used if LAMMPS was built with the From 1579654c97b060c0d62d757d83f71d7da494e0a3 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 6 Oct 2011 18:36:32 +0000 Subject: [PATCH 178/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7042 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/bond_hybrid.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp index eb10d5f5b8..c85c15b02a 100644 --- a/src/bond_hybrid.cpp +++ b/src/bond_hybrid.cpp @@ -287,7 +287,8 @@ void BondHybrid::init_style() double BondHybrid::equilibrium_distance(int i) { - if (map[i] < 0) error->one(FLERR,"Invoked bond equil distance on bond style none"); + if (map[i] < 0) + error->one(FLERR,"Invoked bond equil distance on bond style none"); return styles[map[i]]->equilibrium_distance(i); } From 3e908537397e4dc5910fde07fe3a0b0f5abf4590 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 7 Oct 2011 23:40:08 +0000 Subject: [PATCH 179/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7045 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MAKE/Makefile.g++ | 8 ++++---- src/MAKE/Makefile.serial | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++ index c9480cd026..62f82e372a 100755 --- a/src/MAKE/Makefile.g++ +++ b/src/MAKE/Makefile.g++ @@ -6,10 +6,10 @@ SHELL = /bin/sh # compiler/linker settings # specify flags and libraries needed for your compiler -CC = g++4 +CC = g++ CCFLAGS = -g -O # -Wunused DEPFLAGS = -M -LINK = g++4 +LINK = g++ LINKFLAGS = -g -O LIB = ARCHIVE = ar @@ -35,7 +35,7 @@ LMP_INC = -DLAMMPS_GZIP -DLAMMPS_JPEG MPI_INC = -DMPICH_SKIP_MPICXX MPI_PATH = -MPI_LIB = -lmpich -lpthread +MPI_LIB = -lmpich -lmpl -lpthread # FFT library, OPTIONAL # see discussion in doc/Section_start.html#2_2 (step 6) @@ -57,7 +57,7 @@ FFT_LIB = -lfftw JPG_INC = JPG_PATH = -JPG_LIB = /usr/local/lib/libjpeg.a +JPG_LIB = -ljpeg # --------------------------------------------------------------------- # build rules and dependencies diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial index cc4480d79b..8849b18432 100755 --- a/src/MAKE/Makefile.serial +++ b/src/MAKE/Makefile.serial @@ -7,10 +7,10 @@ SHELL = /bin/sh # generally no need to edit this section # unless additional compiler/linker flags or libraries needed for your machine -CC = g++4 +CC = g++ CCFLAGS = -O DEPFLAGS = -M -LINK = g++4 +LINK = g++ LINKFLAGS = -O LIB = ARCHIVE = ar From 504227e2e602853450f9447501344750db220c57 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 7 Oct 2011 23:44:14 +0000 Subject: [PATCH 180/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7046 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/amber2lmp/amber2lammps.py | 1986 +++++++++++++++---------------- 1 file changed, 993 insertions(+), 993 deletions(-) diff --git a/tools/amber2lmp/amber2lammps.py b/tools/amber2lmp/amber2lammps.py index c47a17cfe6..08bdf38d9e 100644 --- a/tools/amber2lmp/amber2lammps.py +++ b/tools/amber2lmp/amber2lammps.py @@ -1,993 +1,993 @@ -#! /usr/bin/python - -# -# This is amber2lammps, a program written by Keir E. Novik to convert -# Amber files to Lammps files. -# -# Copyright 1999, 2000 Keir E. Novik; all rights reserved. -# -# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README -# - -#============================================================ - -def Pop(S, I=-1): - 'Pop item I from list' - X = S[I] - del S[I] - return X - -#============================================================ - -class Lammps: - - #-------------------------------------------------------- - - def Dump(self): - 'Write out contents of self (intended for debugging)' - Name_list = self.__dict__.keys() - Name_list.sort() - for Name in Name_list: - print Name + ':', self.__dict__[Name] - - #-------------------------------------------------------- - - def Write_data(self, Basename, Item_list): - 'Write the Lammps data to file (used by Write_Lammps)' - import os, sys - - Filename = 'data.' + Basename - - Dir_list = os.listdir('.') - i = 1 - while Filename in Dir_list: - Filename = 'data' + `i` + '.' + Basename - i = i +1 - del i - - print 'Writing', Filename + '...', - sys.stdout.flush() - - try: - F = open(Filename, 'w') - except IOError, Detail: - print '(error:', Detail[1] + '!)' - return - - try: - F.writelines(Item_list) - except IOError, Detail: - print '(error:', Detail[1] + '!)' - F.close() - return - - F.close() - print 'done.' - - #-------------------------------------------------------- - - def Write_Lammps(self, Basename): - 'Write the Lammps data file, ignoring blank sections' - import string - L = [] - - L.append('LAMMPS data file for ' + self.name + '\n\n') - - L.append(`self.atoms` + ' atoms\n') - L.append(`self.bonds` + ' bonds\n') - L.append(`self.angles` + ' angles\n') - L.append(`self.dihedrals` + ' dihedrals\n') - L.append(`self.impropers` + ' impropers\n\n') - - L.append(`self.atom_types` + ' atom types\n') - if self.bonds > 0: - L.append(`self.bond_types` + ' bond types\n') - if self.angles > 0: - L.append(`self.angle_types` + ' angle types\n') - if self.dihedrals > 0: - L.append(`self.dihedral_types` + ' dihedral types\n') - L.append('\n') - - L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n') - L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n') - L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n') - - if self.atom_types != 0: - L.append('Masses\n\n') - for i in range(self.atom_types): - L.append(`i+1` + ' ' + `self.Masses[i]` + '\n') - L.append('\n') - - L.append('Pair Coeffs\n\n') - for i in range(self.atom_types): - L.append(`i+1`) - for j in range(len(self.Nonbond_Coeffs[0])): - L.append(' ' + `self.Nonbond_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.bonds != 0 and self.bond_types != 0: - L.append('Bond Coeffs\n\n') - for i in range(self.bond_types): - L.append(`i+1`) - for j in range(len(self.Bond_Coeffs[0])): - L.append(' ' + `self.Bond_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.angles != 0 and self.angle_types != 0: - L.append('Angle Coeffs\n\n') - for i in range(self.angle_types): - L.append(`i+1`) - for j in range(len(self.Angle_Coeffs[0])): - L.append(' ' + `self.Angle_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.dihedrals != 0 and self.dihedral_types != 0: - L.append('Dihedral Coeffs\n\n') - for i in range(self.dihedral_types): - L.append(`i+1`) - for j in range(len(self.Dihedral_Coeffs[0])): - L.append(' ' + `self.Dihedral_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.atoms != 0: - L.append('Atoms\n\n') - for i in range(self.atoms): - L.append(`i+1`) - for j in range(len(self.Atoms[0])): - L.append(' ' + `self.Atoms[i][j]`) - L.append('\n') - L.append('\n') - - if self.bonds != 0 and self.bond_types != 0: - L.append('Bonds\n\n') - for i in range(self.bonds): - L.append(`i+1`) - for j in range(len(self.Bonds[0])): - L.append(' ' + `self.Bonds[i][j]`) - L.append('\n') - L.append('\n') - - if self.angles != 0 and self.angle_types != 0: - L.append('Angles\n\n') - for i in range(self.angles): - L.append(`i+1`) - for j in range(len(self.Angles[0])): - L.append(' ' + `self.Angles[i][j]`) - L.append('\n') - L.append('\n') - - if self.dihedrals != 0 and self.dihedral_types != 0: - L.append('Dihedrals\n\n') - for i in range(self.dihedrals): - L.append(`i+1`) - for j in range(len(self.Dihedrals[0])): - L.append(' ' + `self.Dihedrals[i][j]`) - L.append('\n') - L.append('\n') - - self.Write_data(Basename, L) - -#============================================================ - -class Amber: - def __init__(self): - 'Initialise the Amber class' - self.CRD_is_read = 0 - self.TOP_is_read = 0 - - #-------------------------------------------------------- - - def Dump(self): - 'Write out contents of self (intended for debugging)' - Name_list = self.__dict__.keys() - Name_list.sort() - for Name in Name_list: - print Name + ':', self.__dict__[Name] - - #-------------------------------------------------------- - - def Coerce_to_Lammps(self): - 'Return the Amber data converted to Lammps format' - - import math - - if self.CRD_is_read and self.TOP_is_read: - l = Lammps() - print 'Converting...', - - l.name = self.ITITL - l.atoms = self.NATOM - l.bonds = self.NBONH + self.MBONA - l.angles = self.NTHETH + self.MTHETA - l.dihedrals = self.NPHIH + self.MPHIA - l.impropers = 0 - l.atom_types = self.NTYPES - l.bond_types = self.NUMBND - l.angle_types = self.NUMANG - l.dihedral_types = self.NPTRA - - Shift = 0 - if self.__dict__.has_key('BOX'): - l.xlo = 0.0 - l.xhi = self.BOX[0] - l.ylo = 0.0 - l.yhi = self.BOX[1] - l.zlo = 0.0 - l.zhi = self.BOX[2] - if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \ - (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \ - (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)): - # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS - # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box, - # please uncomment the below 2 lines. - print '(warning: Currently not shifting the atoms to the periodic box)' - #Shift = 1 - else: - print '(warning: Guessing at periodic box!)', - l.xlo = min(self.X) - l.xhi = max(self.X) - l.ylo = min(self.Y) - l.yhi = max(self.Y) - l.zlo = min(self.Z) - l.zhi = max(self.Z) - - # This doesn't check duplicate values - l.Masses = [] - for i in range(l.atom_types): - l.Masses.append(0) - for i in range(self.NATOM): - l.Masses[self.IAC[i] - 1] = self.AMASS[i] - - l.Nonbond_Coeffs = [] - for i in range(self.NTYPES): - l.Nonbond_Coeffs.append([0,0]) - for i in range(self.NTYPES): - j = self.ICO[i * (self.NTYPES + 1)] - 1 - if self.CN1[j] == 0.0: - l.Nonbond_Coeffs[i][0] = 0.0 - else: - l.Nonbond_Coeffs[i][0] = \ - 0.25 * (self.CN2[j])**2 / self.CN1[j] - if self.CN2[j] == 0.0: - l.Nonbond_Coeffs[i][1] = 0.0 - else: - l.Nonbond_Coeffs[i][1] = \ - (self.CN1[j] / self.CN2[j])**(1.0/6.0) - - l.Bond_Coeffs = [] - for i in range(self.NUMBND): - l.Bond_Coeffs.append([0,0]) - for i in range(self.NUMBND): - l.Bond_Coeffs[i][0] = self.RK[i] - l.Bond_Coeffs[i][1] = self.REQ[i] - - l.Angle_Coeffs = [] - for i in range(self.NUMANG): - l.Angle_Coeffs.append([0,0]) - for i in range(self.NUMANG): - l.Angle_Coeffs[i][0] = self.TK[i] - l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i] - - l.Dihedral_Coeffs = [] - for i in range(self.NPTRA): - l.Dihedral_Coeffs.append([0,0,0]) - for i in range(self.NPTRA): - l.Dihedral_Coeffs[i][0] = self.PK[i] - if self.PHASE[i] == 0: - l.Dihedral_Coeffs[i][1] = 1 - else: - l.Dihedral_Coeffs[i][1] = -1 - l.Dihedral_Coeffs[i][2] = int(self.PN[i]) - - l.Atoms = [] - for i in range(self.NATOM): - x = self.X[i] - y = self.Y[i] - z = self.Z[i] - if Shift: - while x < l.xlo: - x = x + self.BOX[0] - while x > l.xhi: - x = x - self.BOX[0] - while y < l.ylo: - y = y + self.BOX[1] - while y > l.yhi: - y = y - self.BOX[1] - while z < l.zlo: - z = z + self.BOX[2] - while z > l.zhi: - z = z - self.BOX[2] - l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \ - x, y, z]) - - l.Bonds = [] - for i in range(l.bonds): - l.Bonds.append([0,0,0]) - for i in range(self.NBONH): - l.Bonds[i][0] = self.ICBH[i] - l.Bonds[i][1] = abs(self.IBH[i])/3 + 1 - l.Bonds[i][2] = abs(self.JBH[i])/3 + 1 - for i in range(self.NBONA): - l.Bonds[self.NBONH + i][0] = self.ICB[i] - l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1 - l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1 - - l.Angles = [] - for i in range(l.angles): - l.Angles.append([0,0,0,0]) - for i in range(self.NTHETH): - l.Angles[i][0] = self.ICTH[i] - l.Angles[i][1] = abs(self.ITH[i])/3 + 1 - l.Angles[i][2] = abs(self.JTH[i])/3 + 1 - l.Angles[i][3] = abs(self.KTH[i])/3 + 1 - for i in range(self.NTHETA): - l.Angles[self.NTHETH + i][0] = self.ICT[i] - l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1 - l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1 - l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1 - - l.Dihedrals = [] - for i in range(l.dihedrals): - l.Dihedrals.append([0,0,0,0,0]) - for i in range(self.NPHIH): - l.Dihedrals[i][0] = self.ICPH[i] - l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1 - l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1 - l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1 - l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1 - for i in range(self.NPHIA): - l.Dihedrals[self.NPHIH + i][0] = self.ICP[i] - l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1 - - print 'done.' - return l - else: - print '(Error: Not all the Amber data has been read!)' - - #-------------------------------------------------------- - - def Read_data(self, Filename): - 'Read the filename, returning a list of strings' - - import string, sys - - print 'Reading', Filename + '...', - sys.stdout.flush() - - try: - F = open(Filename) - except IOError, Detail: - print '(error:', Detail[1] + '!)' - return - - try: - Lines = F.readlines() - except IOError, Detail: - print '(error:', Detail[1] + '!)' - F.close() - return - - F.close() - - # If the first line is empty, use the Basename - if Filename[-4:] == '.crd': - if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file - Basename = Filename[:string.find(Filename, '.')] - Item_list = [Basename] - print 'Warning: Title not present... Assigning Basename as Title' - else: - Item_list = [] - else: - if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file - Basename = Filename[:string.find(Filename, '.')] - Item_list = [Basename] - print 'Warning: Title not present... Assigning Basename as Title' - else: - Item_list = [] - - for Line in Lines: - if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file. - Item_list.extend(string.split(Line)) - - return Item_list - - #-------------------------------------------------------- - - def Read_CRD(self, Basename): - 'Read the Amber coordinate/restart (.crd) file' - - # The optional velocities and periodic box size are not yet parsed. - - Item_list = self.Read_data(Basename + '.crd') - - if Item_list == None: - return - elif len(Item_list) < 2: - print '(error: File too short!)' - return - - # Parse the data - if self.__dict__.has_key('ITITL'): - if Pop(Item_list,0) != self.ITITL: - print '(warning: ITITL differs!)', - else: - self.ITITL = Pop(Item_list,0) - print self.ITITL #Vikas Modification : Priting the Title - - if self.__dict__.has_key('NATOM'): - if eval(Pop(Item_list,0)) != self.NATOM: - print '(error: NATOM differs!)' - return - else: - self.NATOM = eval(Pop(Item_list,0)) - print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value. - - #if len(Item_list) == 1 + 3 * self.NATOM: - # Vikas' Modification: I changed the condition. - if (len(Item_list)%3) != 0: - self.TIME = eval(Pop(Item_list,0)) - else: - self.TIME = 0 - print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value. - if len(Item_list) < 3 * self.NATOM: - print '(error: File too short!)' - return - - self.X = [] - self.Y = [] - self.Z = [] - for i in range(self.NATOM): - self.X.append(eval(Pop(Item_list,0))) - self.Y.append(eval(Pop(Item_list,0))) - self.Z.append(eval(Pop(Item_list,0))) - - if (self.NATOM == 1) and len(Item_list): - print '(warning: Ambiguity!)', - - if len(Item_list) >= 3 * self.NATOM: - self.VX = [] - self.VY = [] - self.VZ = [] - for i in range(self.NATOM): - self.VX.append(eval(Pop(Item_list,0))) - self.VY.append(eval(Pop(Item_list,0))) - self.VZ.append(eval(Pop(Item_list,0))) - - if len(Item_list) >= 3: - self.BOX = [] - for i in range(3): - self.BOX.append(eval(Pop(Item_list,0))) - - if len(Item_list): - print '(warning: File too large!)', - - print 'done.' - self.CRD_is_read = 1 - - #-------------------------------------------------------- - - def Read_TOP(self, Basename): - 'Read the Amber parameter/topology (.top) file' - Item_list = self.Read_data(Basename + '.top') - - if Item_list == None: - return - elif len(Item_list) < 31: - print '(error: File too short!)' - return - - # Parse the data - if self.__dict__.has_key('ITITL'): - if Pop(Item_list,0) != self.ITITL: - print '(warning: ITITL differs!)' - else: - self.ITITL = Pop(Item_list,0) - print self.ITITL # Printing Self Title - - if self.__dict__.has_key('NATOM'): - if eval(Pop(Item_list,0)) != self.NATOM: - print '(error: NATOM differs!)' - return - else: - self.NATOM = eval(Pop(Item_list,0)) - print self.NATOM # Printing total number of atoms just to make sure that thing are going right - self.NTYPES = eval(Pop(Item_list,0)) - self.NBONH = eval(Pop(Item_list,0)) - self.MBONA = eval(Pop(Item_list,0)) - self.NTHETH = eval(Pop(Item_list,0)) - self.MTHETA = eval(Pop(Item_list,0)) - self.NPHIH = eval(Pop(Item_list,0)) - self.MPHIA = eval(Pop(Item_list,0)) - self.NHPARM = eval(Pop(Item_list,0)) - self.NPARM = eval(Pop(Item_list,0)) - self.NEXT = eval(Pop(Item_list,0)) - self.NRES = eval(Pop(Item_list,0)) - self.NBONA = eval(Pop(Item_list,0)) - self.NTHETA = eval(Pop(Item_list,0)) - self.NPHIA = eval(Pop(Item_list,0)) - self.NUMBND = eval(Pop(Item_list,0)) - self.NUMANG = eval(Pop(Item_list,0)) - self.NPTRA = eval(Pop(Item_list,0)) - self.NATYP = eval(Pop(Item_list,0)) - self.NPHB = eval(Pop(Item_list,0)) - self.IFPERT = eval(Pop(Item_list,0)) - self.NBPER = eval(Pop(Item_list,0)) - self.NGPER = eval(Pop(Item_list,0)) - self.NDPER = eval(Pop(Item_list,0)) - self.MBPER = eval(Pop(Item_list,0)) - self.MGPER = eval(Pop(Item_list,0)) - self.MDPER = eval(Pop(Item_list,0)) - self.IFBOX = eval(Pop(Item_list,0)) - self.NMXRS = eval(Pop(Item_list,0)) - self.IFCAP = eval(Pop(Item_list,0)) - - #.................................................... - - if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \ - 2*(self.NRES + self.NUMBND + self.NUMANG) + \ - 3*self.NPTRA + self.NATYP: - print '(error: File too short!)' - return -1 - - self.IGRAPH = [] - Pop(Item_list,0) - - # A little kludge is needed here, since the IGRAPH strings are - # not separated by spaces if 4 characters in length. - for i in range(self.NATOM): - if len(Item_list[0]) > 4: - Item_list.insert(1, Item_list[0][4:]) - Item_list.insert(1, Item_list[0][0:4]) - del Item_list[0] - self.IGRAPH.append(Pop(Item_list,0)) - - # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file. - print 'Reading Charges...' - self.CHRG = [] - for i in range(self.NATOM): - self.CHRG.append(eval(Pop(Item_list,0))) - - print 'Reading Atomic Masses...' - self.AMASS = [] - for i in range(self.NATOM): - self.AMASS.append(eval(Pop(Item_list,0))) - - print 'Reading Atom Types...' - self.IAC = [] - for i in range(self.NATOM): - self.IAC.append(eval(Pop(Item_list,0))) - - print 'Reading Excluded Atoms...' - self.NUMEX = [] - for i in range(self.NATOM): - self.NUMEX.append(eval(Pop(Item_list,0))) - - print 'Reading Non-bonded Parameter Index...' - self.ICO = [] - for i in range(self.NTYPES**2): - self.ICO.append(eval(Pop(Item_list,0))) - - print 'Reading Residue Labels...' - self.LABRES = [] - for i in range(self.NRES): - self.LABRES.append(Pop(Item_list,0)) - - print 'Reading Residues Starting Pointers...' - self.IPRES = [] - for i in range(self.NRES): - self.IPRES.append(eval(Pop(Item_list,0))) - - print 'Reading Bond Force Constants...' - self.RK = [] - for i in range(self.NUMBND): - self.RK.append(eval(Pop(Item_list,0))) - - print 'Reading Equilibrium Bond Values...' - self.REQ = [] - for i in range(self.NUMBND): - self.REQ.append(eval(Pop(Item_list,0))) - - print 'Reading Angle Force Constants...' - self.TK = [] - for i in range(self.NUMANG): - self.TK.append(eval(Pop(Item_list,0))) - - print 'Reading Equilibrium Angle Values...' - self.TEQ = [] - for i in range(self.NUMANG): - self.TEQ.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Force Constants...' - self.PK = [] - for i in range(self.NPTRA): - self.PK.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Periodicity...' - self.PN = [] - for i in range(self.NPTRA): - self.PN.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Phase...' - self.PHASE = [] - for i in range(self.NPTRA): - self.PHASE.append(eval(Pop(Item_list,0))) - - print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though - self.SOLTY = [] - for i in range(self.NATYP): - self.SOLTY.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2: - print '(error: File too short!)' - return -1 - - print 'Reading LJ A Coefficient...' - self.CN1 = [] - for i in range(self.NTYPES * (self.NTYPES + 1) / 2): - self.CN1.append(eval(Pop(Item_list,0))) - - print 'Reading LJ B Coefficient...' - self.CN2 = [] - for i in range(self.NTYPES * (self.NTYPES + 1) / 2): - self.CN2.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \ - 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA): - print '(error: File too short!)' - return -1 - - print 'Reading Bonds which include hydrogen...' - self.IBH = [] - self.JBH = [] - self.ICBH = [] - for i in range(self.NBONH): - self.IBH.append(eval(Pop(Item_list,0))) - self.JBH.append(eval(Pop(Item_list,0))) - self.ICBH.append(eval(Pop(Item_list,0))) - - print 'Reading Bonds which dont include hydrogen...' - self.IB = [] - self.JB = [] - self.ICB = [] - for i in range(self.NBONA): - self.IB.append(eval(Pop(Item_list,0))) - self.JB.append(eval(Pop(Item_list,0))) - self.ICB.append(eval(Pop(Item_list,0))) - - print 'Reading Angles which include hydrogen...' - self.ITH = [] - self.JTH = [] - self.KTH = [] - self.ICTH = [] - for i in range(self.NTHETH): - self.ITH.append(eval(Pop(Item_list,0))) - self.JTH.append(eval(Pop(Item_list,0))) - self.KTH.append(eval(Pop(Item_list,0))) - self.ICTH.append(eval(Pop(Item_list,0))) - - print 'Reading Angles which dont include hydrogen...' - self.IT = [] - self.JT = [] - self.KT = [] - self.ICT = [] - for i in range(self.NTHETA): - self.IT.append(eval(Pop(Item_list,0))) - self.JT.append(eval(Pop(Item_list,0))) - self.KT.append(eval(Pop(Item_list,0))) - self.ICT.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedrals which include hydrogen...' - self.IPH = [] - self.JPH = [] - self.KPH = [] - self.LPH = [] - self.ICPH = [] - for i in range(self.NPHIH): - self.IPH.append(eval(Pop(Item_list,0))) - self.JPH.append(eval(Pop(Item_list,0))) - self.KPH.append(eval(Pop(Item_list,0))) - self.LPH.append(eval(Pop(Item_list,0))) - self.ICPH.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedrals which dont include hydrogen...' - self.IP = [] - self.JP = [] - self.KP = [] - self.LP = [] - self.ICP = [] - for i in range(self.NPHIA): - self.IP.append(eval(Pop(Item_list,0))) - self.JP.append(eval(Pop(Item_list,0))) - self.KP.append(eval(Pop(Item_list,0))) - self.LP.append(eval(Pop(Item_list,0))) - self.ICP.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM: - print '(error: File too short!)' - return -1 - - print 'Reading Excluded Atom List...' - self.NATEX = [] - for i in range(self.NEXT): - self.NATEX.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...' - self.ASOL = [] - for i in range(self.NPHB): - self.ASOL.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...' - self.BSOL = [] - for i in range(self.NPHB): - self.BSOL.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond Cut...' # I think it is not being used nowadays - self.HBCUT = [] - for i in range(self.NPHB): - self.HBCUT.append(eval(Pop(Item_list,0))) - - print 'Reading Amber Atom Types for each atom...' - self.ISYMBL = [] - for i in range(self.NATOM): - self.ISYMBL.append(Pop(Item_list,0)) - - print 'Reading Tree Chain Classification...' - self.ITREE = [] - for i in range(self.NATOM): - self.ITREE.append(Pop(Item_list,0)) - - print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module - self.JOIN = [] - for i in range(self.NATOM): - self.JOIN.append(eval(Pop(Item_list,0))) - - print 'Reading IRotate...' # Currently unused in Sander and Gibbs - self.IROTAT = [] - for i in range(self.NATOM): - self.IROTAT.append(eval(Pop(Item_list,0))) - - #.................................................... - - if self.IFBOX > 0: - if len(Item_list) < 3: - print '(error: File too short!)' - return -1 - - print 'Reading final residue which is part of solute...' - self.IPTRES = eval(Pop(Item_list,0)) - print 'Reading total number of molecules...' - self.NSPM = eval(Pop(Item_list,0)) - print 'Reading first solvent moleule index...' - self.NSPSOL = eval(Pop(Item_list,0)) - - if len(Item_list) < self.NSPM + 4: - print '(error: File too short!)' - return -1 - - print 'Reading atom per molecule...' - self.NSP = [] - for i in range(self.NSPM): - self.NSP.append(eval(Pop(Item_list,0))) - - self.BETA = eval(Pop(Item_list,0)) - - print 'Reading Box Dimensions...' - if self.__dict__.has_key('BOX'): - BOX = [] - for i in range(3): - BOX.append(eval(Pop(Item_list,0))) - for i in range(3): - if BOX[i] != self.BOX[i]: - print '(warning: BOX differs!)', - break - del BOX - else: - self.BOX = [] - for i in range(3): - self.BOX.append(eval(Pop(Item_list,0))) - - #.................................................... - - if self.IFCAP > 0: - if len(Item_list) < 5: - print '(error: File too short!)' - return -1 - print 'Reading ICAP variables::: For details, refer to online AMBER format manual' - self.NATCAP = eval(Pop(Item_list,0)) - self.CUTCAP = eval(Pop(Item_list,0)) - self.XCAP = eval(Pop(Item_list,0)) - self.YCAP = eval(Pop(Item_list,0)) - self.ZCAP = eval(Pop(Item_list,0)) - - #.................................................... - - if self.IFPERT > 0: - if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \ - 6 * self.NDPER + self.NRES + 6 * self.NATOM: - print '(error: File too short!)' - return -1 - - print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual' - self.IBPER = [] - self.JBPER = [] - for i in range(self.NBPER): - self.IBPER.append(eval(Pop(Item_list,0))) - self.JBPER.append(eval(Pop(Item_list,0))) - - self.ICBPER = [] - for i in range(2 * self.NBPER): - self.ICBPER.append(eval(Pop(Item_list,0))) - - self.ITPER = [] - self.JTPER = [] - self.KTPER = [] - for i in range(self.NGPER): - self.ITPER.append(eval(Pop(Item_list,0))) - self.JTPER.append(eval(Pop(Item_list,0))) - self.KTPER.append(eval(Pop(Item_list,0))) - - self.ICTPER = [] - for i in range(2 * self.NGPER): - self.ICTPER.append(eval(Pop(Item_list,0))) - - self.IPPER = [] - self.JPPER = [] - self.KPPER = [] - self.LPPER = [] - for i in range(self.NDPER): - self.IPPER.append(eval(Pop(Item_list,0))) - self.JPPER.append(eval(Pop(Item_list,0))) - self.KPPER.append(eval(Pop(Item_list,0))) - self.LPPER.append(eval(Pop(Item_list,0))) - - self.ICPPER = [] - for i in range(2 * self.NDPER): - self.ICPPER.append(eval(Pop(Item_list,0))) - - LABRES = [] - for i in range(self.NRES): - LABRES.append(Pop(Item_list,0)) - for i in range(self.NRES): - if LABRES[i] != self.LABRES[i]: - print '(warning: BOX differs!)', - break - - self.IGRPER = [] - for i in range(self.NATOM): - self.IGRPER.append(eval(Pop(Item_list,0))) - - self.ISMPER = [] - for i in range(self.NATOM): - self.ISMPER.append(eval(Pop(Item_list,0))) - - self.ALMPER = [] - for i in range(self.NATOM): - self.ALMPER.append(eval(Pop(Item_list,0))) - - self.IAPER = [] - for i in range(self.NATOM): - self.IAPER.append(eval(Pop(Item_list,0))) - - self.IACPER = [] - for i in range(self.NATOM): - self.IACPER.append(eval(Pop(Item_list,0))) - - self.CGPER = [] - for i in range(self.NATOM): - self.CGPER.append(eval(Pop(Item_list,0))) - - #.................................................... - - self.IPOL = 0 - if self.IPOL == 1: - if len(Item_list) < self.NATOM: - print '(error: File too short!)' - return -1 - print 'Reading Polarizability Data. For details, refer to online AMBER format manual' - self.ATPOL = [] - for i in range(self.NATOM): - self.ATPOL.append(eval(Pop(Item_list,0))) - - if self.IFPERT == 1: - if len(Item_list) < self.NATOM: - print '(error: File too short!)' - return -1 - self.ATPOL1 = [] - for i in range(self.NATOM): - self.ATPOL1.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list): - print '(warning: File too large!)', - - print 'done.' - self.TOP_is_read = 1 - -#============================================================ - -def Find_Amber_files(): - 'Look for sets of Amber files to process' - '''If not passed anything on the command line, look for pairs of - Amber files (.crd and .top) in the current directory. For - each set if there is no corresponding Lammps file (data.), or it is - older than any of the Amber files, add its basename to a list of - strings. This list is returned by the function''' - - # Date and existence checks not yet implemented - - import os, sys - - Basename_list = [] - - # Extract basenames from command line - for Name in sys.argv[1:]: - if Name[-4:] == '.crd': - Basename_list.append(Name[:-4]) - else: - if Name[-4:] == '.top': - Basename_list.append(Name[:-4]) - else: - Basename_list.append(Name) - - # Remove duplicate basenames - for Basename in Basename_list[:]: - while Basename_list.count(Basename) > 1: - Basename_list.remove(Basename) - - if Basename_list == []: - print 'Looking for Amber files...', - Dir_list = os.listdir('.') - Dir_list.sort() - for File in Dir_list: - if File[-4:] == '.top': - Basename = File[:-4] - if (Basename + '.crd') in Dir_list: - Basename_list.append(Basename) - if Basename_list != []: - print 'found', - for i in range(len(Basename_list)-1): - print Basename_list[i] + ',', - print Basename_list[-1] + '\n' - - if Basename_list == []: - print 'none.\n' - - return Basename_list - -#============================================================ - -def Convert_Amber_files(): - 'Handle the whole conversion process' - print - print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!' - print - Basename_list = Find_Amber_files() - for Basename in Basename_list: - a = Amber() - a.Read_CRD(Basename) - if a.CRD_is_read: - a.Read_TOP(Basename) - if a.TOP_is_read: - l = a.Coerce_to_Lammps() - l.Write_Lammps(Basename) - del l - del a - print - -#============================================================ - -Convert_Amber_files() +#! /usr/bin/python + +# +# This is amber2lammps, a program written by Keir E. Novik to convert +# Amber files to Lammps files. +# +# Copyright 1999, 2000 Keir E. Novik; all rights reserved. +# +# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README +# Bug Fixed :Third argument in Dihedral Coeffs section is an integer - Ketan S Khare September 26, 2011 + +#============================================================ + +def Pop(S, I=-1): + 'Pop item I from list' + X = S[I] + del S[I] + return X + +#============================================================ + +class Lammps: + + #-------------------------------------------------------- + + def Dump(self): + 'Write out contents of self (intended for debugging)' + Name_list = self.__dict__.keys() + Name_list.sort() + for Name in Name_list: + print Name + ':', self.__dict__[Name] + + #-------------------------------------------------------- + + def Write_data(self, Basename, Item_list): + 'Write the Lammps data to file (used by Write_Lammps)' + import os, sys + + Filename = 'data.' + Basename + + Dir_list = os.listdir('.') + i = 1 + while Filename in Dir_list: + Filename = 'data' + `i` + '.' + Basename + i = i +1 + del i + + print 'Writing', Filename + '...', + sys.stdout.flush() + + try: + F = open(Filename, 'w') + except IOError, Detail: + print '(error:', Detail[1] + '!)' + return + + try: + F.writelines(Item_list) + except IOError, Detail: + print '(error:', Detail[1] + '!)' + F.close() + return + + F.close() + print 'done.' + + #-------------------------------------------------------- + + def Write_Lammps(self, Basename): + 'Write the Lammps data file, ignoring blank sections' + import string + L = [] + + L.append('LAMMPS data file for ' + self.name + '\n\n') + + L.append(`self.atoms` + ' atoms\n') + L.append(`self.bonds` + ' bonds\n') + L.append(`self.angles` + ' angles\n') + L.append(`self.dihedrals` + ' dihedrals\n') + L.append(`self.impropers` + ' impropers\n\n') + + L.append(`self.atom_types` + ' atom types\n') + if self.bonds > 0: + L.append(`self.bond_types` + ' bond types\n') + if self.angles > 0: + L.append(`self.angle_types` + ' angle types\n') + if self.dihedrals > 0: + L.append(`self.dihedral_types` + ' dihedral types\n') + L.append('\n') + + L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n') + L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n') + L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n') + + if self.atom_types != 0: + L.append('Masses\n\n') + for i in range(self.atom_types): + L.append(`i+1` + ' ' + `self.Masses[i]` + '\n') + L.append('\n') + + L.append('Pair Coeffs\n\n') + for i in range(self.atom_types): + L.append(`i+1`) + for j in range(len(self.Nonbond_Coeffs[0])): + L.append(' ' + `self.Nonbond_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.bonds != 0 and self.bond_types != 0: + L.append('Bond Coeffs\n\n') + for i in range(self.bond_types): + L.append(`i+1`) + for j in range(len(self.Bond_Coeffs[0])): + L.append(' ' + `self.Bond_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.angles != 0 and self.angle_types != 0: + L.append('Angle Coeffs\n\n') + for i in range(self.angle_types): + L.append(`i+1`) + for j in range(len(self.Angle_Coeffs[0])): + L.append(' ' + `self.Angle_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.dihedrals != 0 and self.dihedral_types != 0: + L.append('Dihedral Coeffs\n\n') + for i in range(self.dihedral_types): + L.append(`i+1`) + for j in range(len(self.Dihedral_Coeffs[0])): + L.append(' ' + `self.Dihedral_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.atoms != 0: + L.append('Atoms\n\n') + for i in range(self.atoms): + L.append(`i+1`) + for j in range(len(self.Atoms[0])): + L.append(' ' + `self.Atoms[i][j]`) + L.append('\n') + L.append('\n') + + if self.bonds != 0 and self.bond_types != 0: + L.append('Bonds\n\n') + for i in range(self.bonds): + L.append(`i+1`) + for j in range(len(self.Bonds[0])): + L.append(' ' + `self.Bonds[i][j]`) + L.append('\n') + L.append('\n') + + if self.angles != 0 and self.angle_types != 0: + L.append('Angles\n\n') + for i in range(self.angles): + L.append(`i+1`) + for j in range(len(self.Angles[0])): + L.append(' ' + `self.Angles[i][j]`) + L.append('\n') + L.append('\n') + + if self.dihedrals != 0 and self.dihedral_types != 0: + L.append('Dihedrals\n\n') + for i in range(self.dihedrals): + L.append(`i+1`) + for j in range(len(self.Dihedrals[0])): + L.append(' ' + `self.Dihedrals[i][j]`) + L.append('\n') + L.append('\n') + + self.Write_data(Basename, L) + +#============================================================ + +class Amber: + def __init__(self): + 'Initialise the Amber class' + self.CRD_is_read = 0 + self.TOP_is_read = 0 + + #-------------------------------------------------------- + + def Dump(self): + 'Write out contents of self (intended for debugging)' + Name_list = self.__dict__.keys() + Name_list.sort() + for Name in Name_list: + print Name + ':', self.__dict__[Name] + + #-------------------------------------------------------- + + def Coerce_to_Lammps(self): + 'Return the Amber data converted to Lammps format' + + import math + + if self.CRD_is_read and self.TOP_is_read: + l = Lammps() + print 'Converting...', + + l.name = self.ITITL + l.atoms = self.NATOM + l.bonds = self.NBONH + self.MBONA + l.angles = self.NTHETH + self.MTHETA + l.dihedrals = self.NPHIH + self.MPHIA + l.impropers = 0 + l.atom_types = self.NTYPES + l.bond_types = self.NUMBND + l.angle_types = self.NUMANG + l.dihedral_types = self.NPTRA + + Shift = 0 + if self.__dict__.has_key('BOX'): + l.xlo = 0.0 + l.xhi = self.BOX[0] + l.ylo = 0.0 + l.yhi = self.BOX[1] + l.zlo = 0.0 + l.zhi = self.BOX[2] + if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \ + (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \ + (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)): + # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS + # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box, + # please uncomment the below 2 lines. + print '(warning: Currently not shifting the atoms to the periodic box)' + #Shift = 1 + else: + print '(warning: Guessing at periodic box!)', + l.xlo = min(self.X) + l.xhi = max(self.X) + l.ylo = min(self.Y) + l.yhi = max(self.Y) + l.zlo = min(self.Z) + l.zhi = max(self.Z) + + # This doesn't check duplicate values + l.Masses = [] + for i in range(l.atom_types): + l.Masses.append(0) + for i in range(self.NATOM): + l.Masses[self.IAC[i] - 1] = self.AMASS[i] + + l.Nonbond_Coeffs = [] + for i in range(self.NTYPES): + l.Nonbond_Coeffs.append([0,0]) + for i in range(self.NTYPES): + j = self.ICO[i * (self.NTYPES + 1)] - 1 + if self.CN1[j] == 0.0: + l.Nonbond_Coeffs[i][0] = 0.0 + else: + l.Nonbond_Coeffs[i][0] = \ + 0.25 * (self.CN2[j])**2 / self.CN1[j] + if self.CN2[j] == 0.0: + l.Nonbond_Coeffs[i][1] = 0.0 + else: + l.Nonbond_Coeffs[i][1] = \ + (self.CN1[j] / self.CN2[j])**(1.0/6.0) + + l.Bond_Coeffs = [] + for i in range(self.NUMBND): + l.Bond_Coeffs.append([0,0]) + for i in range(self.NUMBND): + l.Bond_Coeffs[i][0] = self.RK[i] + l.Bond_Coeffs[i][1] = self.REQ[i] + + l.Angle_Coeffs = [] + for i in range(self.NUMANG): + l.Angle_Coeffs.append([0,0]) + for i in range(self.NUMANG): + l.Angle_Coeffs[i][0] = self.TK[i] + l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i] + + l.Dihedral_Coeffs = [] + for i in range(self.NPTRA): + l.Dihedral_Coeffs.append([0,0,0]) + for i in range(self.NPTRA): + l.Dihedral_Coeffs[i][0] = self.PK[i] + if self.PHASE[i] == 0: + l.Dihedral_Coeffs[i][1] = 1 + else: + l.Dihedral_Coeffs[i][1] = -1 + l.Dihedral_Coeffs[i][2] = int(self.PN[i]) + + l.Atoms = [] + for i in range(self.NATOM): + x = self.X[i] + y = self.Y[i] + z = self.Z[i] + if Shift: + while x < l.xlo: + x = x + self.BOX[0] + while x > l.xhi: + x = x - self.BOX[0] + while y < l.ylo: + y = y + self.BOX[1] + while y > l.yhi: + y = y - self.BOX[1] + while z < l.zlo: + z = z + self.BOX[2] + while z > l.zhi: + z = z - self.BOX[2] + l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \ + x, y, z]) + + l.Bonds = [] + for i in range(l.bonds): + l.Bonds.append([0,0,0]) + for i in range(self.NBONH): + l.Bonds[i][0] = self.ICBH[i] + l.Bonds[i][1] = abs(self.IBH[i])/3 + 1 + l.Bonds[i][2] = abs(self.JBH[i])/3 + 1 + for i in range(self.NBONA): + l.Bonds[self.NBONH + i][0] = self.ICB[i] + l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1 + l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1 + + l.Angles = [] + for i in range(l.angles): + l.Angles.append([0,0,0,0]) + for i in range(self.NTHETH): + l.Angles[i][0] = self.ICTH[i] + l.Angles[i][1] = abs(self.ITH[i])/3 + 1 + l.Angles[i][2] = abs(self.JTH[i])/3 + 1 + l.Angles[i][3] = abs(self.KTH[i])/3 + 1 + for i in range(self.NTHETA): + l.Angles[self.NTHETH + i][0] = self.ICT[i] + l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1 + l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1 + l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1 + + l.Dihedrals = [] + for i in range(l.dihedrals): + l.Dihedrals.append([0,0,0,0,0]) + for i in range(self.NPHIH): + l.Dihedrals[i][0] = self.ICPH[i] + l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1 + l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1 + l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1 + l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1 + for i in range(self.NPHIA): + l.Dihedrals[self.NPHIH + i][0] = self.ICP[i] + l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1 + + print 'done.' + return l + else: + print '(Error: Not all the Amber data has been read!)' + + #-------------------------------------------------------- + + def Read_data(self, Filename): + 'Read the filename, returning a list of strings' + + import string, sys + + print 'Reading', Filename + '...', + sys.stdout.flush() + + try: + F = open(Filename) + except IOError, Detail: + print '(error:', Detail[1] + '!)' + return + + try: + Lines = F.readlines() + except IOError, Detail: + print '(error:', Detail[1] + '!)' + F.close() + return + + F.close() + + # If the first line is empty, use the Basename + if Filename[-4:] == '.crd': + if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file + Basename = Filename[:string.find(Filename, '.')] + Item_list = [Basename] + print 'Warning: Title not present... Assigning Basename as Title' + else: + Item_list = [] + else: + if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file + Basename = Filename[:string.find(Filename, '.')] + Item_list = [Basename] + print 'Warning: Title not present... Assigning Basename as Title' + else: + Item_list = [] + + for Line in Lines: + if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file. + Item_list.extend(string.split(Line)) + + return Item_list + + #-------------------------------------------------------- + + def Read_CRD(self, Basename): + 'Read the Amber coordinate/restart (.crd) file' + + # The optional velocities and periodic box size are not yet parsed. + + Item_list = self.Read_data(Basename + '.crd') + + if Item_list == None: + return + elif len(Item_list) < 2: + print '(error: File too short!)' + return + + # Parse the data + if self.__dict__.has_key('ITITL'): + if Pop(Item_list,0) != self.ITITL: + print '(warning: ITITL differs!)', + else: + self.ITITL = Pop(Item_list,0) + print self.ITITL #Vikas Modification : Priting the Title + + if self.__dict__.has_key('NATOM'): + if eval(Pop(Item_list,0)) != self.NATOM: + print '(error: NATOM differs!)' + return + else: + self.NATOM = eval(Pop(Item_list,0)) + print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value. + + #if len(Item_list) == 1 + 3 * self.NATOM: + # Vikas' Modification: I changed the condition. + if (len(Item_list)%3) != 0: + self.TIME = eval(Pop(Item_list,0)) + else: + self.TIME = 0 + print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value. + if len(Item_list) < 3 * self.NATOM: + print '(error: File too short!)' + return + + self.X = [] + self.Y = [] + self.Z = [] + for i in range(self.NATOM): + self.X.append(eval(Pop(Item_list,0))) + self.Y.append(eval(Pop(Item_list,0))) + self.Z.append(eval(Pop(Item_list,0))) + + if (self.NATOM == 1) and len(Item_list): + print '(warning: Ambiguity!)', + + if len(Item_list) >= 3 * self.NATOM: + self.VX = [] + self.VY = [] + self.VZ = [] + for i in range(self.NATOM): + self.VX.append(eval(Pop(Item_list,0))) + self.VY.append(eval(Pop(Item_list,0))) + self.VZ.append(eval(Pop(Item_list,0))) + + if len(Item_list) >= 3: + self.BOX = [] + for i in range(3): + self.BOX.append(eval(Pop(Item_list,0))) + + if len(Item_list): + print '(warning: File too large!)', + + print 'done.' + self.CRD_is_read = 1 + + #-------------------------------------------------------- + + def Read_TOP(self, Basename): + 'Read the Amber parameter/topology (.top) file' + Item_list = self.Read_data(Basename + '.top') + + if Item_list == None: + return + elif len(Item_list) < 31: + print '(error: File too short!)' + return + + # Parse the data + if self.__dict__.has_key('ITITL'): + if Pop(Item_list,0) != self.ITITL: + print '(warning: ITITL differs!)' + else: + self.ITITL = Pop(Item_list,0) + print self.ITITL # Printing Self Title + + if self.__dict__.has_key('NATOM'): + if eval(Pop(Item_list,0)) != self.NATOM: + print '(error: NATOM differs!)' + return + else: + self.NATOM = eval(Pop(Item_list,0)) + print self.NATOM # Printing total number of atoms just to make sure that thing are going right + self.NTYPES = eval(Pop(Item_list,0)) + self.NBONH = eval(Pop(Item_list,0)) + self.MBONA = eval(Pop(Item_list,0)) + self.NTHETH = eval(Pop(Item_list,0)) + self.MTHETA = eval(Pop(Item_list,0)) + self.NPHIH = eval(Pop(Item_list,0)) + self.MPHIA = eval(Pop(Item_list,0)) + self.NHPARM = eval(Pop(Item_list,0)) + self.NPARM = eval(Pop(Item_list,0)) + self.NEXT = eval(Pop(Item_list,0)) + self.NRES = eval(Pop(Item_list,0)) + self.NBONA = eval(Pop(Item_list,0)) + self.NTHETA = eval(Pop(Item_list,0)) + self.NPHIA = eval(Pop(Item_list,0)) + self.NUMBND = eval(Pop(Item_list,0)) + self.NUMANG = eval(Pop(Item_list,0)) + self.NPTRA = eval(Pop(Item_list,0)) + self.NATYP = eval(Pop(Item_list,0)) + self.NPHB = eval(Pop(Item_list,0)) + self.IFPERT = eval(Pop(Item_list,0)) + self.NBPER = eval(Pop(Item_list,0)) + self.NGPER = eval(Pop(Item_list,0)) + self.NDPER = eval(Pop(Item_list,0)) + self.MBPER = eval(Pop(Item_list,0)) + self.MGPER = eval(Pop(Item_list,0)) + self.MDPER = eval(Pop(Item_list,0)) + self.IFBOX = eval(Pop(Item_list,0)) + self.NMXRS = eval(Pop(Item_list,0)) + self.IFCAP = eval(Pop(Item_list,0)) + + #.................................................... + + if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \ + 2*(self.NRES + self.NUMBND + self.NUMANG) + \ + 3*self.NPTRA + self.NATYP: + print '(error: File too short!)' + return -1 + + self.IGRAPH = [] + Pop(Item_list,0) + + # A little kludge is needed here, since the IGRAPH strings are + # not separated by spaces if 4 characters in length. + for i in range(self.NATOM): + if len(Item_list[0]) > 4: + Item_list.insert(1, Item_list[0][4:]) + Item_list.insert(1, Item_list[0][0:4]) + del Item_list[0] + self.IGRAPH.append(Pop(Item_list,0)) + + # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file. + print 'Reading Charges...' + self.CHRG = [] + for i in range(self.NATOM): + self.CHRG.append(eval(Pop(Item_list,0))) + + print 'Reading Atomic Masses...' + self.AMASS = [] + for i in range(self.NATOM): + self.AMASS.append(eval(Pop(Item_list,0))) + + print 'Reading Atom Types...' + self.IAC = [] + for i in range(self.NATOM): + self.IAC.append(eval(Pop(Item_list,0))) + + print 'Reading Excluded Atoms...' + self.NUMEX = [] + for i in range(self.NATOM): + self.NUMEX.append(eval(Pop(Item_list,0))) + + print 'Reading Non-bonded Parameter Index...' + self.ICO = [] + for i in range(self.NTYPES**2): + self.ICO.append(eval(Pop(Item_list,0))) + + print 'Reading Residue Labels...' + self.LABRES = [] + for i in range(self.NRES): + self.LABRES.append(Pop(Item_list,0)) + + print 'Reading Residues Starting Pointers...' + self.IPRES = [] + for i in range(self.NRES): + self.IPRES.append(eval(Pop(Item_list,0))) + + print 'Reading Bond Force Constants...' + self.RK = [] + for i in range(self.NUMBND): + self.RK.append(eval(Pop(Item_list,0))) + + print 'Reading Equilibrium Bond Values...' + self.REQ = [] + for i in range(self.NUMBND): + self.REQ.append(eval(Pop(Item_list,0))) + + print 'Reading Angle Force Constants...' + self.TK = [] + for i in range(self.NUMANG): + self.TK.append(eval(Pop(Item_list,0))) + + print 'Reading Equilibrium Angle Values...' + self.TEQ = [] + for i in range(self.NUMANG): + self.TEQ.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Force Constants...' + self.PK = [] + for i in range(self.NPTRA): + self.PK.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Periodicity...' + self.PN = [] + for i in range(self.NPTRA): + self.PN.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Phase...' + self.PHASE = [] + for i in range(self.NPTRA): + self.PHASE.append(eval(Pop(Item_list,0))) + + print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though + self.SOLTY = [] + for i in range(self.NATYP): + self.SOLTY.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2: + print '(error: File too short!)' + return -1 + + print 'Reading LJ A Coefficient...' + self.CN1 = [] + for i in range(self.NTYPES * (self.NTYPES + 1) / 2): + self.CN1.append(eval(Pop(Item_list,0))) + + print 'Reading LJ B Coefficient...' + self.CN2 = [] + for i in range(self.NTYPES * (self.NTYPES + 1) / 2): + self.CN2.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \ + 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA): + print '(error: File too short!)' + return -1 + + print 'Reading Bonds which include hydrogen...' + self.IBH = [] + self.JBH = [] + self.ICBH = [] + for i in range(self.NBONH): + self.IBH.append(eval(Pop(Item_list,0))) + self.JBH.append(eval(Pop(Item_list,0))) + self.ICBH.append(eval(Pop(Item_list,0))) + + print 'Reading Bonds which dont include hydrogen...' + self.IB = [] + self.JB = [] + self.ICB = [] + for i in range(self.NBONA): + self.IB.append(eval(Pop(Item_list,0))) + self.JB.append(eval(Pop(Item_list,0))) + self.ICB.append(eval(Pop(Item_list,0))) + + print 'Reading Angles which include hydrogen...' + self.ITH = [] + self.JTH = [] + self.KTH = [] + self.ICTH = [] + for i in range(self.NTHETH): + self.ITH.append(eval(Pop(Item_list,0))) + self.JTH.append(eval(Pop(Item_list,0))) + self.KTH.append(eval(Pop(Item_list,0))) + self.ICTH.append(eval(Pop(Item_list,0))) + + print 'Reading Angles which dont include hydrogen...' + self.IT = [] + self.JT = [] + self.KT = [] + self.ICT = [] + for i in range(self.NTHETA): + self.IT.append(eval(Pop(Item_list,0))) + self.JT.append(eval(Pop(Item_list,0))) + self.KT.append(eval(Pop(Item_list,0))) + self.ICT.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedrals which include hydrogen...' + self.IPH = [] + self.JPH = [] + self.KPH = [] + self.LPH = [] + self.ICPH = [] + for i in range(self.NPHIH): + self.IPH.append(eval(Pop(Item_list,0))) + self.JPH.append(eval(Pop(Item_list,0))) + self.KPH.append(eval(Pop(Item_list,0))) + self.LPH.append(eval(Pop(Item_list,0))) + self.ICPH.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedrals which dont include hydrogen...' + self.IP = [] + self.JP = [] + self.KP = [] + self.LP = [] + self.ICP = [] + for i in range(self.NPHIA): + self.IP.append(eval(Pop(Item_list,0))) + self.JP.append(eval(Pop(Item_list,0))) + self.KP.append(eval(Pop(Item_list,0))) + self.LP.append(eval(Pop(Item_list,0))) + self.ICP.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM: + print '(error: File too short!)' + return -1 + + print 'Reading Excluded Atom List...' + self.NATEX = [] + for i in range(self.NEXT): + self.NATEX.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...' + self.ASOL = [] + for i in range(self.NPHB): + self.ASOL.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...' + self.BSOL = [] + for i in range(self.NPHB): + self.BSOL.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond Cut...' # I think it is not being used nowadays + self.HBCUT = [] + for i in range(self.NPHB): + self.HBCUT.append(eval(Pop(Item_list,0))) + + print 'Reading Amber Atom Types for each atom...' + self.ISYMBL = [] + for i in range(self.NATOM): + self.ISYMBL.append(Pop(Item_list,0)) + + print 'Reading Tree Chain Classification...' + self.ITREE = [] + for i in range(self.NATOM): + self.ITREE.append(Pop(Item_list,0)) + + print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module + self.JOIN = [] + for i in range(self.NATOM): + self.JOIN.append(eval(Pop(Item_list,0))) + + print 'Reading IRotate...' # Currently unused in Sander and Gibbs + self.IROTAT = [] + for i in range(self.NATOM): + self.IROTAT.append(eval(Pop(Item_list,0))) + + #.................................................... + + if self.IFBOX > 0: + if len(Item_list) < 3: + print '(error: File too short!)' + return -1 + + print 'Reading final residue which is part of solute...' + self.IPTRES = eval(Pop(Item_list,0)) + print 'Reading total number of molecules...' + self.NSPM = eval(Pop(Item_list,0)) + print 'Reading first solvent moleule index...' + self.NSPSOL = eval(Pop(Item_list,0)) + + if len(Item_list) < self.NSPM + 4: + print '(error: File too short!)' + return -1 + + print 'Reading atom per molecule...' + self.NSP = [] + for i in range(self.NSPM): + self.NSP.append(eval(Pop(Item_list,0))) + + self.BETA = eval(Pop(Item_list,0)) + + print 'Reading Box Dimensions...' + if self.__dict__.has_key('BOX'): + BOX = [] + for i in range(3): + BOX.append(eval(Pop(Item_list,0))) + for i in range(3): + if BOX[i] != self.BOX[i]: + print '(warning: BOX differs!)', + break + del BOX + else: + self.BOX = [] + for i in range(3): + self.BOX.append(eval(Pop(Item_list,0))) + + #.................................................... + + if self.IFCAP > 0: + if len(Item_list) < 5: + print '(error: File too short!)' + return -1 + print 'Reading ICAP variables::: For details, refer to online AMBER format manual' + self.NATCAP = eval(Pop(Item_list,0)) + self.CUTCAP = eval(Pop(Item_list,0)) + self.XCAP = eval(Pop(Item_list,0)) + self.YCAP = eval(Pop(Item_list,0)) + self.ZCAP = eval(Pop(Item_list,0)) + + #.................................................... + + if self.IFPERT > 0: + if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \ + 6 * self.NDPER + self.NRES + 6 * self.NATOM: + print '(error: File too short!)' + return -1 + + print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual' + self.IBPER = [] + self.JBPER = [] + for i in range(self.NBPER): + self.IBPER.append(eval(Pop(Item_list,0))) + self.JBPER.append(eval(Pop(Item_list,0))) + + self.ICBPER = [] + for i in range(2 * self.NBPER): + self.ICBPER.append(eval(Pop(Item_list,0))) + + self.ITPER = [] + self.JTPER = [] + self.KTPER = [] + for i in range(self.NGPER): + self.ITPER.append(eval(Pop(Item_list,0))) + self.JTPER.append(eval(Pop(Item_list,0))) + self.KTPER.append(eval(Pop(Item_list,0))) + + self.ICTPER = [] + for i in range(2 * self.NGPER): + self.ICTPER.append(eval(Pop(Item_list,0))) + + self.IPPER = [] + self.JPPER = [] + self.KPPER = [] + self.LPPER = [] + for i in range(self.NDPER): + self.IPPER.append(eval(Pop(Item_list,0))) + self.JPPER.append(eval(Pop(Item_list,0))) + self.KPPER.append(eval(Pop(Item_list,0))) + self.LPPER.append(eval(Pop(Item_list,0))) + + self.ICPPER = [] + for i in range(2 * self.NDPER): + self.ICPPER.append(eval(Pop(Item_list,0))) + + LABRES = [] + for i in range(self.NRES): + LABRES.append(Pop(Item_list,0)) + for i in range(self.NRES): + if LABRES[i] != self.LABRES[i]: + print '(warning: BOX differs!)', + break + + self.IGRPER = [] + for i in range(self.NATOM): + self.IGRPER.append(eval(Pop(Item_list,0))) + + self.ISMPER = [] + for i in range(self.NATOM): + self.ISMPER.append(eval(Pop(Item_list,0))) + + self.ALMPER = [] + for i in range(self.NATOM): + self.ALMPER.append(eval(Pop(Item_list,0))) + + self.IAPER = [] + for i in range(self.NATOM): + self.IAPER.append(eval(Pop(Item_list,0))) + + self.IACPER = [] + for i in range(self.NATOM): + self.IACPER.append(eval(Pop(Item_list,0))) + + self.CGPER = [] + for i in range(self.NATOM): + self.CGPER.append(eval(Pop(Item_list,0))) + + #.................................................... + + self.IPOL = 0 + if self.IPOL == 1: + if len(Item_list) < self.NATOM: + print '(error: File too short!)' + return -1 + print 'Reading Polarizability Data. For details, refer to online AMBER format manual' + self.ATPOL = [] + for i in range(self.NATOM): + self.ATPOL.append(eval(Pop(Item_list,0))) + + if self.IFPERT == 1: + if len(Item_list) < self.NATOM: + print '(error: File too short!)' + return -1 + self.ATPOL1 = [] + for i in range(self.NATOM): + self.ATPOL1.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list): + print '(warning: File too large!)', + + print 'done.' + self.TOP_is_read = 1 + +#============================================================ + +def Find_Amber_files(): + 'Look for sets of Amber files to process' + '''If not passed anything on the command line, look for pairs of + Amber files (.crd and .top) in the current directory. For + each set if there is no corresponding Lammps file (data.), or it is + older than any of the Amber files, add its basename to a list of + strings. This list is returned by the function''' + + # Date and existence checks not yet implemented + + import os, sys + + Basename_list = [] + + # Extract basenames from command line + for Name in sys.argv[1:]: + if Name[-4:] == '.crd': + Basename_list.append(Name[:-4]) + else: + if Name[-4:] == '.top': + Basename_list.append(Name[:-4]) + else: + Basename_list.append(Name) + + # Remove duplicate basenames + for Basename in Basename_list[:]: + while Basename_list.count(Basename) > 1: + Basename_list.remove(Basename) + + if Basename_list == []: + print 'Looking for Amber files...', + Dir_list = os.listdir('.') + Dir_list.sort() + for File in Dir_list: + if File[-4:] == '.top': + Basename = File[:-4] + if (Basename + '.crd') in Dir_list: + Basename_list.append(Basename) + if Basename_list != []: + print 'found', + for i in range(len(Basename_list)-1): + print Basename_list[i] + ',', + print Basename_list[-1] + '\n' + + if Basename_list == []: + print 'none.\n' + + return Basename_list + +#============================================================ + +def Convert_Amber_files(): + 'Handle the whole conversion process' + print + print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!' + print + Basename_list = Find_Amber_files() + for Basename in Basename_list: + a = Amber() + a.Read_CRD(Basename) + if a.CRD_is_read: + a.Read_TOP(Basename) + if a.TOP_is_read: + l = a.Coerce_to_Lammps() + l.Write_Lammps(Basename) + del l + del a + print + +#============================================================ + +Convert_Amber_files() From c8fa1bd5df840960f1692c3756017cb689bfd816 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 7 Oct 2011 23:50:07 +0000 Subject: [PATCH 181/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7047 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MANYBODY/pair_comb.cpp | 238 ++++++++++++++++++++++++++++--------- src/MANYBODY/pair_comb.h | 15 ++- 2 files changed, 195 insertions(+), 58 deletions(-) diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 5d0db94997..5c47b8dcf1 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Tzu-Ray Shan (U Florida, rayshan@ufl.edu) + Contributing author: Tzu-Ray Shan (U Florida, present: tnshan@sandia.gov) LAMMPS implementation of the Charge-optimized many-body (COMB) potential based on the HELL MD program (Prof Simon Phillpot, UF, sphil@mse.ufl.edu) and Aidan Thompson's Tersoff code in LAMMPS @@ -32,11 +32,13 @@ #include "memory.h" #include "error.h" #include "group.h" +#include "update.h" using namespace LAMMPS_NS; #define MAXLINE 1024 #define DELTA 4 +#define PGDELTA 1 /* ---------------------------------------------------------------------- */ @@ -52,6 +54,7 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp) nmax = 0; NCo = NULL; + bbij = NULL; nelements = 0; elements = NULL; @@ -68,6 +71,11 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp) dphin = NULL; erpaw = NULL; + sht_num = NULL; + sht_first = NULL; + maxpage = 0; + pages = NULL; + // set comm size needed by this Pair comm_forward = 1; @@ -84,6 +92,7 @@ PairComb::~PairComb() if (elements) for (int i = 0; i < nelements; i++) delete [] elements[i]; + delete [] elements; memory->sfree(params); memory->destroy(elem2param); @@ -95,6 +104,9 @@ PairComb::~PairComb() memory->destroy(phin); memory->destroy(dphin); memory->destroy(erpaw); + memory->destroy(bbij); + memory->destroy(sht_num); + memory->destroy(sht_first); if (allocated) { memory->destroy(setflag); @@ -122,17 +134,25 @@ void PairComb::compute(int eflag, int vflag) double yaself; double potal,fac11,fac11e; double vionij,fvionij,sr1,sr2,sr3,Eov,Fov; + int sht_jnum, *sht_jlist; evdwl = ecoul = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = vflag_atom = 0; - // grow coordination array if necessary + // Build short range neighbor list + // int every=neighbor->every; + // int ntimestep=update->ntimestep; + // if(ntimestep <= 1 || (ntimestep % every == 0)) + Short_neigh(); + // grow coordination array if necessary if (atom->nmax > nmax) { memory->destroy(NCo); + memory->destroy(bbij); nmax = atom->nmax; memory->create(NCo,nmax,"pair:NCo"); + memory->create(bbij,nmax,nmax,"pair:bbij"); } double **x = atom->x; @@ -177,6 +197,8 @@ void PairComb::compute(int eflag, int vflag) jlist = firstneigh[i]; jnum = numneigh[i]; + sht_jlist = sht_first[i]; + sht_jnum = sht_num[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; @@ -258,8 +280,8 @@ void PairComb::compute(int eflag, int vflag) // accumulate coordination number information if (cor_flag) { - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; + for (jj = 0; jj < sht_jnum; jj++) { + j = sht_jlist[jj]; j &= NEIGHMASK; jtype = map[type[j]]; iparam_ij = elem2param[itype][jtype][jtype]; @@ -277,11 +299,12 @@ void PairComb::compute(int eflag, int vflag) } // three-body interactions - // skip immediately if I-J is not within cutoff + // half i-j loop - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; + for (jj = 0; jj < sht_jnum; jj++) { + j = sht_jlist[jj]; j &= NEIGHMASK; + jtype = map[type[j]]; iparam_ij = elem2param[itype][jtype][jtype]; @@ -301,9 +324,9 @@ void PairComb::compute(int eflag, int vflag) zeta_ij = 0.0; cuo_flag1 = 0; cuo_flag2 = 0; - for (kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - k = jlist[kk]; + for (kk = 0; kk < sht_jnum; kk++) { + k = sht_jlist[kk]; + if (j == k) continue; k &= NEIGHMASK; ktype = map[type[k]]; iparam_ijk = elem2param[itype][jtype][ktype]; @@ -324,9 +347,9 @@ void PairComb::compute(int eflag, int vflag) if (cuo_flag1 && cuo_flag2) cuo_flag = 1; else cuo_flag = 0; - force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair, - prefactor,eflag,evdwl,iq,jq); - + force_zeta(¶ms[iparam_ij],eflag,i,j,rsq1,zeta_ij, + iq,jq,fpair,prefactor,evdwl); + // over-coordination correction for HfO2 if (cor_flag && NCo[i] != 0) @@ -346,9 +369,9 @@ void PairComb::compute(int eflag, int vflag) // attractive term via loop over k (3-body forces) - for (kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - k = jlist[kk]; + for (kk = 0; kk < sht_jnum; kk++) { + k = sht_jlist[kk]; + if (j == k) continue; k &= NEIGHMASK; ktype = map[type[k]]; iparam_ijk = elem2param[itype][jtype][ktype]; @@ -530,6 +553,11 @@ void PairComb::init_style() int irequest = neighbor->request(this); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->ghost = 1; + + pgsize = neighbor->pgsize; + oneatom = neighbor->oneatom; + if (maxpage == 0) add_pages(0); } /* ---------------------------------------------------------------------- @@ -799,11 +827,12 @@ void PairComb::setup() // set cutmax to max of all params - cutmax = 0.0; + cutmax = cutmin = 0.0; cor_flag = 0; for (m = 0; m < nparams; m++) { if (params[m].cut > cutmax) cutmax = params[m].cut; if (params[m].lcut > cutmax) cutmax = params[m].lcut; + if (params[m].cutsq > cutmin) cutmin = params[m].cutsq+1.0; if (params[m].hfocor > 0.0001) cor_flag = 1; } } @@ -930,7 +959,7 @@ double PairComb::elp(Param *param, double rsqij, double rsqik, comtt += param->aconf *(4.0-(rmu-c123)*(rmu-c123)); } - return 0.5 * fck * comtt; + return 1.0 * fck * comtt; } return 0.0; @@ -996,10 +1025,10 @@ void PairComb::flp(Param *param, double rsqij, double rsqik, com4k = fcj * fck_d * comtt; com5 = fcj * fck * comtt_d; - ffj1 =-0.5*(com5/(rij*rik)); - ffj2 = 0.5*(com5*rmu/rsqij); + ffj1 =-1.0*(com5/(rij*rik)); + ffj2 = 1.0*(com5*rmu/rsqij); ffk1 = ffj1; - ffk2 = 0.5*(-com4k/rik+com5*rmu/rsqik); + ffk2 = 1.0*(-com4k/rik+com5*rmu/rsqik); } else { ffj1 = 0.0; ffj2 = 0.0; @@ -1024,9 +1053,9 @@ void PairComb::flp(Param *param, double rsqij, double rsqik, /* ---------------------------------------------------------------------- */ -void PairComb::force_zeta(Param *param, double rsq, double zeta_ij, - double &fforce, double &prefactor, - int eflag, double &eng, double iq, double jq) +void PairComb::force_zeta(Param *param, int eflag, int i, int j, double rsq, + double zeta_ij, double iq, double jq, double &fforce, + double &prefactor, double &eng) { double r,fa,fa_d,bij; @@ -1035,11 +1064,13 @@ void PairComb::force_zeta(Param *param, double rsq, double zeta_ij, fa = comb_fa(r,param,iq,jq); fa_d = comb_fa_d(r,param,iq,jq); bij = comb_bij(zeta_ij,param); + bbij[i][j] = bij; + + // force fforce = 0.5*bij*fa_d / r; prefactor = -0.5*fa * comb_bij_d(zeta_ij,param); // eng = attractive energy - if (eflag) eng = 0.5*bij*fa; } @@ -1343,6 +1374,7 @@ void PairComb::sm_table() double exp2ear,exp2ebr,exp2earsh,exp2ebrsh,fafbsh,dfafbsh; int n = atom->ntypes; + int nmax = atom->nmax; dra = 0.001; // lookup table step size drin = 0.1; // starting distance of 1/r @@ -1351,7 +1383,7 @@ void PairComb::sm_table() nntypes = int((n+1)*n/2); // interaction types ncoul = int((rc-drin)/dra)+1; - +/* memory->destroy(intype); memory->destroy(fafb); memory->destroy(dfafb); @@ -1359,7 +1391,7 @@ void PairComb::sm_table() memory->destroy(phin); memory->destroy(dphin); memory->destroy(erpaw); - +*/ // allocate arrays memory->create(intype,n,n,"pair:intype"); @@ -1369,6 +1401,11 @@ void PairComb::sm_table() memory->create(phin,ncoul,nntypes,"pair:phin"); memory->create(dphin,ncoul,nntypes,"pair:dphin"); memory->create(erpaw,25000,2,"pair:erpaw"); + memory->create(NCo,nmax,"pair:NCo"); + memory->create(bbij,nmax,nmax,"pair:bbij"); + memory->create(sht_num,nmax,"pair:sht_num"); + sht_first = (int **) memory->smalloc(nmax*sizeof(int *), + "pair:sht_first"); // set interaction number: 0-0=0, 1-1=1, 0-1=1-0=2 @@ -1614,7 +1651,7 @@ void PairComb::field(Param *param, double rsq, double iq,double jq, double PairComb::yasu_char(double *qf_fix, int &igroup) { - int i,j,k,ii,jj,kk,jnum; + int i,j,k,ii,jj,kk,jnum,itag,jtag; int itype,jtype,ktype,iparam_i,iparam_ij,iparam_ijk; double xtmp,ytmp,ztmp; double rsq1,rsq2,delr1[3],delr2[3],zeta_ij; @@ -1622,10 +1659,12 @@ double PairComb::yasu_char(double *qf_fix, int &igroup) double iq,jq,fqi,fqj,fqij,fqjj; double potal,fac11,fac11e,sr1,sr2,sr3; int mr1,mr2,mr3,inty; + int sht_jnum, *sht_jlist; double **x = atom->x; double *q = atom->q; int *type = atom->type; + int *tag = atom->tag; int inum = list->inum; ilist = list->ilist; @@ -1656,6 +1695,7 @@ double PairComb::yasu_char(double *qf_fix, int &igroup) for (ii = 0; ii < inum; ii ++) { i = ilist[ii]; + itag = tag[i]; if (mask[i] & groupbit) { itype = map[type[i]]; xtmp = x[i][0]; @@ -1672,10 +1712,24 @@ double PairComb::yasu_char(double *qf_fix, int &igroup) jlist = firstneigh[i]; jnum = numneigh[i]; + sht_jlist = sht_first[i]; + sht_jnum = sht_num[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; + 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] < x[i][2]) 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; + } + jtype = map[type[j]]; jq = q[j]; @@ -1706,38 +1760,31 @@ double PairComb::yasu_char(double *qf_fix, int &igroup) qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqij,fqjj); fqi += fqij; qf[j] += fqjj; + } - // polarization field charge force // three-body interactions + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = map[type[j]]; + jq = q[j]; + + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + rsq1 = vec3_dot(delr1,delr1); + + iparam_ij = elem2param[itype][jtype][jtype]; if (rsq1 > params[iparam_ij].cutsq) continue; - zeta_ij = 0.0; - - for (kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - k = jlist[kk]; - k &= NEIGHMASK; - ktype = map[type[k]]; - iparam_ijk = elem2param[itype][jtype][ktype]; - - delr2[0] = x[k][0] - xtmp; - delr2[1] = x[k][1] - ytmp; - delr2[2] = x[k][2] - ztmp; - rsq2 = vec3_dot(delr2,delr2); - - if (rsq2 > params[iparam_ijk].cutsq) continue; - zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); - } - // charge force in Aij and Bij - qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj); + qfo_short(¶ms[iparam_ij],i,j,rsq1,iq,jq,fqij,fqjj); fqi += fqij; qf[j] += fqjj; } - qf[i] += fqi; - } } @@ -1809,7 +1856,7 @@ void PairComb::qfo_direct(int inty, int mr1, int mr2, int mr3, erfcc = sr1*erpaw[mr1][0] + sr2*erpaw[mr2][0] + sr3*erpaw[mr3][0]; fafbn1= sr1*fafb[mr1][inty] + sr2*fafb[mr2][inty] + sr3*fafb[mr3][inty]; vm = (erfcc/r * esucon - fac11e); - fqij = 0.5 * (vm+esucon*fafbn1); + fqij = 1.0 * (vm+esucon*fafbn1); } /* ---------------------------------------------------------------------- */ @@ -1835,13 +1882,13 @@ void PairComb::qfo_field(Param *param, double rsq,double iq,double jq, // field correction charge force - fqij = 0.5 * rf5 * (cmj1 + 2.0 * iq * cmj2); - fqjj = 0.5 * rf5 * (cmi1 + 2.0 * jq * cmi2); + fqij = 1.0 * rf5 * (cmj1 + 2.0 * iq * cmj2); + fqjj = 1.0 * rf5 * (cmi1 + 2.0 * jq * cmi2); } /* ---------------------------------------------------------------------- */ -void PairComb::qfo_short(Param *param, double rsq, double zeta_ij, +void PairComb::qfo_short(Param *param, int i, int j, double rsq, double iq, double jq, double &fqij, double &fqjj) { double r,tmp_fc,tmp_fc_d,tmp_exp1,tmp_exp2; @@ -1866,7 +1913,7 @@ void PairComb::qfo_short(Param *param, double rsq, double zeta_ij, tmp_fc_d = comb_fc_d(r,param); tmp_exp1 = exp(-param->rlm1 * r); tmp_exp2 = exp(-param->rlm2 * r); - bij = comb_bij(zeta_ij,param); + bij = bbij[i][j]; //comb_bij(zeta_ij,param); arr1 = 2.22850; arr2 = 1.89350; fc2j = comb_fc2(r); @@ -2025,5 +2072,86 @@ double PairComb::memory_usage() double bytes = maxeatom * sizeof(double); bytes += maxvatom*6 * sizeof(double); bytes += nmax * sizeof(int); + bytes += nmax * nmax * sizeof(int); return bytes; } +/* ---------------------------------------------------------------------- */ + +void PairComb::Short_neigh() +{ + int nj,npntj,*neighptrj,itype,jtype; + int iparam_ij,*ilist,*jlist,*numneigh,**firstneigh; + int inum,jnum,i,j,ii,jj; + double xtmp,ytmp,ztmp,rr,rsq,delrj[3]; + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int ntype = atom->ntypes; + + if (atom->nmax > nmax) { + nmax = int(1.0 * atom->nmax); + memory->sfree(sht_num); + memory->sfree(sht_first); + memory->create(sht_num,nmax,"pair:sht_num"); + sht_first = (int **) memory->smalloc(nmax*sizeof(int *), + "pair:sht_first"); + } + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + npage = npntj = 0; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + + if(pgsize - npntj < oneatom) { + npntj = 0; + npage++; + if (npage == maxpage) add_pages(npage); + } + + nj = 0; + neighptrj = &pages[npage][npntj]; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + iparam_ij = elem2param[itype][jtype][jtype]; + + delrj[0] = xtmp - x[j][0]; + delrj[1] = ytmp - x[j][1]; + delrj[2] = ztmp - x[j][2]; + rsq = vec3_dot(delrj,delrj); + + if (rsq > cutmin) continue; + neighptrj[nj++] = j; + } + sht_first[i] = neighptrj; + sht_num[i] = nj; + npntj += nj; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairComb::add_pages(int npage) +{ + maxpage += PGDELTA; + pages = (int **) + memory->srealloc(pages,maxpage*sizeof(int *),"pair:pages"); + for (int i = npage; i < maxpage; i++) + memory->create(pages[i],pgsize,"pair:pages[i]"); +} + +/* ---------------------------------------------------------------------- */ diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h index 555cf7509b..c8782b4bbf 100644 --- a/src/MANYBODY/pair_comb.h +++ b/src/MANYBODY/pair_comb.h @@ -76,6 +76,7 @@ class PairComb : public Pair { double *charge; int **intype, *typeno; int *NCo, cor_flag, cuo_flag, cuo_flag1, cuo_flag2; + double **bbij; void allocate(); virtual void read_file(char *); @@ -83,8 +84,8 @@ class PairComb : public Pair { virtual void repulsive(Param *, double, double &, int, double &, double, double); double zeta(Param *, double, double, double *, double *); - void force_zeta(Param *, double, double, double &, double &, - int, double &, double,double); + void force_zeta(Param *, int, int, int, double, double, double, double, + double &, double &, double &); void attractive(Param *, double, double, double, double *, double *, double *, double *, double *); double elp(Param *, double, double, double *, double *); @@ -115,7 +116,8 @@ class PairComb : public Pair { double,double,double,double &,double &); void field(Param *,double,double,double,double &,double &); double qfo_self(Param *, double, double); - void qfo_short(Param *, double, double, double, double, double &, double &); + void qfo_short(Param *, int, int, double, double, double, + double &, double &); void qfo_direct (int, int, int, int, double, double, double, double, double, double &); void qfo_field(Param *, double,double ,double ,double &, double &); @@ -126,6 +128,13 @@ class PairComb : public Pair { int pack_comm(int , int *, double *, int, int *); void unpack_comm(int , int , double *); + // Short range neighbor list + void add_pages(int ); + void Short_neigh(); + int npage, maxpage, pgsize, oneatom, **pages; + int *sht_num, **sht_first; // short-range neighbor list + double cutmin; + // vector functions, inline for efficiency inline double vec3_dot(double *x, double *y) { From 4591d9958dbb931b5fc6de69b2c6069f2c634922 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 7 Oct 2011 23:52:06 +0000 Subject: [PATCH 182/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7048 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/Makefile.defaults | 2 +- lib/cuda/Makefile.lammps | 4 ++-- lib/gpu/Makefile.linux | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/cuda/Makefile.defaults b/lib/cuda/Makefile.defaults index 3f39f7d606..ea0c53a349 100644 --- a/lib/cuda/Makefile.defaults +++ b/lib/cuda/Makefile.defaults @@ -3,7 +3,7 @@ precision ?= 1 #GPU architecture (compute capability): 13, 20, 21 -arch ?= 20 +arch ?= 21 #Using cufft (should not be changed) cufft ?= 1 diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps index 172fbc91ec..711e827a65 100644 --- a/lib/cuda/Makefile.lammps +++ b/lib/cuda/Makefile.lammps @@ -1,6 +1,6 @@ # Settings that the LAMMPS build will import when this package library is used - CUDA_FLAGS = -I/usr/local/cuda/include -I../../lib/cuda -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20 - CUDA_USRLIB_CONDITIONAL = -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft +CUDA_FLAGS := -I/usr/local/cuda/include -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20 +CUDA_USRLIB_CONDITIONAL := -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft user-cuda_SYSINC = ${CUDA_FLAGS} user-cuda_SYSLIB = -lcuda -lcudart -lrt diff --git a/lib/gpu/Makefile.linux b/lib/gpu/Makefile.linux index 1777187010..c8dd8350d1 100644 --- a/lib/gpu/Makefile.linux +++ b/lib/gpu/Makefile.linux @@ -20,8 +20,10 @@ CUDA_HOME = /usr/local/cuda NVCC = nvcc +# Tesla CUDA +CUDA_ARCH = -arch=sm_21 # newer CUDA -CUDA_ARCH = -arch=sm_13 +#CUDA_ARCH = -arch=sm_13 # older CUDA #CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE From 2182b0443bba24509324dd3eee4da964bb2a5bd8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 7 Oct 2011 23:52:09 +0000 Subject: [PATCH 183/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7049 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 4d760c21f6..e5b656e825 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "6 Oct 2011" +#define LAMMPS_VERSION "7 Oct 2011" From c1bfbd8e616501b33fbd00cd5a78c206ff828d99 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 14:58:50 +0000 Subject: [PATCH 184/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7057 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/input.cpp | 2 +- src/lammps.cpp | 38 +++++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index ca4d450d72..2251335b43 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -89,7 +89,7 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp) int iarg = 0; while (iarg < argc) { if (strcmp(argv[iarg],"-var") == 0 || strcmp(argv[iarg],"-v") == 0) { - int jarg = iarg+2; + int jarg = iarg+3; while (jarg < argc && argv[jarg][0] != '-') jarg++; variable->set(argv[iarg+1],jarg-iarg-2,&argv[iarg+2]); iarg = jarg; diff --git a/src/lammps.cpp b/src/lammps.cpp index 09b6a487de..f316a03ad7 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -81,7 +81,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) if (strcmp(arg[iarg],"-partition") == 0 || strcmp(arg[iarg],"-p") == 0) { universe->existflag = 1; - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); iarg++; while (iarg < narg && arg[iarg][0] != '-') { universe->add_world(arg[iarg]); @@ -89,27 +90,32 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) } } else if (strcmp(arg[iarg],"-in") == 0 || strcmp(arg[iarg],"-i") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); inflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-screen") == 0 || strcmp(arg[iarg],"-sc") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); screenflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-log") == 0 || strcmp(arg[iarg],"-l") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); logflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-var") == 0 || strcmp(arg[iarg],"-v") == 0) { - if (iarg+3 > narg) error->universe_all(FLERR,"Invalid command-line argument"); - iarg += 2; + if (iarg+3 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); + iarg += 3; while (iarg < narg && arg[iarg][0] != '-') iarg++; } else if (strcmp(arg[iarg],"-echo") == 0 || strcmp(arg[iarg],"-e") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-pscreen") == 0 || strcmp(arg[iarg],"-ps") == 0) { @@ -125,14 +131,16 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) iarg += 2; } else if (strcmp(arg[iarg],"-cuda") == 0 || strcmp(arg[iarg],"-c") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); if (strcmp(arg[iarg+1],"on") == 0) cudaflag = 1; else if (strcmp(arg[iarg+1],"off") == 0) cudaflag = 0; else error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-suffix") == 0 || strcmp(arg[iarg],"-sf") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); delete [] suffix; int n = strlen(arg[iarg+1]) + 1; suffix = new char[n]; @@ -141,7 +149,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) iarg += 2; } else if (strcmp(arg[iarg],"-help") == 0 || strcmp(arg[iarg],"-h") == 0) { - if (iarg+1 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+1 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); helpflag = 1; iarg += 1; } else error->universe_all(FLERR,"Invalid command-line argument"); @@ -334,10 +343,12 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) int mpisize; MPI_Type_size(MPI_LMP_TAGINT,&mpisize); if (mpisize != sizeof(tagint)) - error->all(FLERR,"MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); + error->all(FLERR, + "MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); MPI_Type_size(MPI_LMP_BIGINT,&mpisize); if (mpisize != sizeof(bigint)) - error->all(FLERR,"MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); + error->all(FLERR, + "MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); #ifdef LAMMPS_SMALLBIG if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 8) @@ -352,7 +363,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) error->all(FLERR,"Small, tag, big integers are not sized correctly"); #endif - if (sizeof(tagint) == 8) error->all(FLERR,"64-bit atom IDs are not yet supported"); + if (sizeof(tagint) == 8) + error->all(FLERR,"64-bit atom IDs are not yet supported"); // create CUDA class if USER-CUDA installed, unless explicitly switched off // instantiation creates dummy CUDA class if USER-CUDA is not installed From 6a2a96053c405a3a87ce17820391ba8df0e7ff3b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 15:01:46 +0000 Subject: [PATCH 185/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7058 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_start.html | 6 ++++++ doc/Section_start.txt | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/doc/Section_start.html b/doc/Section_start.html index bfe24d404e..438f879dd6 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -1016,6 +1016,12 @@ defining index and other kinds of variables and


      2.7 LAMMPS screen output diff --git a/doc/Section_start.txt b/doc/Section_start.txt index 5ae3fb715c..674dec45b7 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -1008,6 +1008,12 @@ defining index and other kinds of variables and "this section"_Section_commands.html#cmd_2 for more info on using variables in input scripts. +NOTE: Currently, the command-line parser looks for arguments that +start with "-" to indicate new switches. Thus you cannot specify +multiple variable values if any of they start with a "-", e.g. a +negative numeric value. It is OK if the first value1 starts with a +"-", since it is automatically skipped. + :line 2.7 LAMMPS screen output :h4,link(start_7) From 76da1a753ba17d47166c7f793423d31b7ed6bed8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 15:03:34 +0000 Subject: [PATCH 186/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7059 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index e5b656e825..9da39c4204 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "7 Oct 2011" +#define LAMMPS_VERSION "10 Oct 2011" From 6d849fea0e361c349098e9d5b747b903ac8e9e45 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 16:26:58 +0000 Subject: [PATCH 187/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7061 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MOLECULE/pair_hbond_dreiding_lj.cpp | 7 ++++--- src/MOLECULE/pair_hbond_dreiding_morse.cpp | 7 ++++--- src/fix_addforce.cpp | 15 ++++++++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index cb5429b3f4..eae9e4aa83 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -76,7 +76,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) { int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype; double delx,dely,delz,rsq,rsq1,rsq2,r1,r2; - double factor_hb,force_angle,force_kernel,evdwl,eng_lj; + double factor_hb,force_angle,force_kernel,evdwl,eng_lj,ehbond; double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double fi[3],fj[3],delr1[3],delr2[3]; double r2inv,r10inv; @@ -84,7 +84,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) int *ilist,*jlist,*klist,*numneigh,**firstneigh; Param *pm; - evdwl = 0.0; + evdwl = ehbond = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -186,6 +186,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (eflag) { evdwl = eng_lj * pow(c,pm->ap); evdwl *= factor_hb; + ehbond += evdwl; } a = factor_hb*force_angle/s; @@ -234,7 +235,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (eflag_global) { pvector[0] = hbcount; - pvector[1] = evdwl; + pvector[1] = ehbond; } } diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp index 2e70d928d1..ebd3b27ef0 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp @@ -46,14 +46,14 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) { int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype; double delx,dely,delz,rsq,rsq1,rsq2,r1,r2; - double factor_hb,force_angle,force_kernel,evdwl; + double factor_hb,force_angle,force_kernel,evdwl,ehbond; double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double fi[3],fj[3],delr1[3],delr2[3]; double r,dr,dexp,eng_morse,switch1,switch2; int *ilist,*jlist,*klist,*numneigh,**firstneigh; Param *pm; - evdwl = 0.0; + evdwl = ehbond = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -154,6 +154,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (eflag) { evdwl = eng_morse * pow(c,params[m].ap); evdwl *= factor_hb; + ehbond += evdwl; } a = factor_hb*force_angle/s; @@ -202,7 +203,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (eflag_global) { pvector[0] = hbcount; - pvector[1] = evdwl; + pvector[1] = ehbond; } } diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp index 16a3c1feab..fee57525d8 100644 --- a/src/fix_addforce.cpp +++ b/src/fix_addforce.cpp @@ -137,28 +137,32 @@ void FixAddForce::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (xvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (yvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (zvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (estr) { evar = input->variable->find(estr); - if (evar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (evar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->atomstyle(evar)) estyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } else estyle = NONE; @@ -167,7 +171,8 @@ void FixAddForce::init() if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all(FLERR,"Region ID for fix addforce does not exist"); + if (iregion == -1) + error->all(FLERR,"Region ID for fix addforce does not exist"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) From 789f069c2bc857259e0b73ed310976e9f4e10bba Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 16:33:07 +0000 Subject: [PATCH 188/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7062 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- examples/README | 1 + examples/dreiding/README | 5 + examples/dreiding/ch3oh.box.dreiding.bgf | 780 +++++++++ .../ch3oh.box.dreiding.cerius2.eng.dat | 56 + examples/dreiding/data.dreiding | 1400 +++++++++++++++++ examples/dreiding/in.dreiding | 39 + .../dreiding/log.dreiding.11Oct11.linux.1 | 97 ++ .../dreiding/log.dreiding.11Oct11.linux.4 | 121 ++ 8 files changed, 2499 insertions(+) create mode 100644 examples/dreiding/README create mode 100644 examples/dreiding/ch3oh.box.dreiding.bgf create mode 100644 examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat create mode 100644 examples/dreiding/data.dreiding create mode 100644 examples/dreiding/in.dreiding create mode 100644 examples/dreiding/log.dreiding.11Oct11.linux.1 create mode 100644 examples/dreiding/log.dreiding.11Oct11.linux.4 diff --git a/examples/README b/examples/README index ffad2e66c5..814497cf81 100644 --- a/examples/README +++ b/examples/README @@ -29,6 +29,7 @@ colloid: big colloid particles in a small particle solvent, 2d system comb: models using the COMB potential crack: crack propagation in a 2d solid dipole: point dipolar particles, 2d system +dreiding: methanol via Dreiding FF eim: NaCl using the EIM potential ellipse: ellipsoidal particles in spherical solvent, 2d system flow: Couette and Poiseuille flow in a 2d channel diff --git a/examples/dreiding/README b/examples/dreiding/README new file mode 100644 index 0000000000..351f7e9e5c --- /dev/null +++ b/examples/dreiding/README @@ -0,0 +1,5 @@ +The LAMMPS input script and data file were built to +match the Cerius Dreiding files included +in this directory (ch3oh.box.*) so that you +can compare LAMMPS output to a Dreiding implementation +in the Cerius code. diff --git a/examples/dreiding/ch3oh.box.dreiding.bgf b/examples/dreiding/ch3oh.box.dreiding.bgf new file mode 100644 index 0000000000..b9431153aa --- /dev/null +++ b/examples/dreiding/ch3oh.box.dreiding.bgf @@ -0,0 +1,780 @@ +XTLGRF 200 +DESCRP Model6 +REMARK BGF file created by Cerius2 +FORCEFIELD DREIDING +PERIOD 111 +AXES ZYX +SGNAME P 1 1 1 +CRYSTX 19.99689 19.12816 19.46971 90.00000 90.00000 90.00000 +CELLS -1 1 -1 1 -1 1 +FORMAT ATOM (a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5, i3,i2,1x,f8.5) +HETATM 1 C1 RES A 444 9.75768 9.43603 9.44978 C_3 4 0 0.03193 +HETATM 2 O2 RES A 444 9.07001 9.89252 10.61030 O_3 2 2 -0.39965 +HETATM 3 H3 RES A 444 9.56169 8.37372 9.30573 H_ 1 0 0.05269 +HETATM 4 H4 RES A 444 9.40633 9.98872 8.57739 H_ 1 0 0.05269 +HETATM 5 H5 RES A 444 10.83081 9.58873 9.56849 H_ 1 0 0.05269 +HETATM 6 H6 RES A 444 9.28861 10.84826 10.67569 H___A 1 0 0.20964 +HETATM 7 C7 RES A 444 7.87790 6.57305 4.37926 C_3 4 0 0.03193 +HETATM 8 O8 RES A 444 9.21046 6.55811 3.88167 O_3 2 2 -0.39965 +HETATM 9 H9 RES A 444 7.42565 7.54437 4.17519 H_ 1 0 0.05269 +HETATM 10 H10 RES A 444 7.28908 5.79550 3.89029 H_ 1 0 0.05269 +HETATM 11 H11 RES A 444 7.88159 6.39628 5.45605 H_ 1 0 0.05269 +HETATM 12 H12 RES A 444 9.55621 5.66386 4.09964 H___A 1 0 0.20964 +HETATM 13 C13 RES A 444 19.38728 8.01844 0.29841 C_3 4 0 0.03193 +HETATM 14 O14 RES A 444 18.30059 8.67235 0.94403 O_3 2 2 -0.39965 +HETATM 15 H15 RES A 444 20.09420 7.66052 1.04704 H_ 1 0 0.05269 +HETATM 16 H16 RES A 444 19.01558 7.17130 -0.27928 H_ 1 0 0.05269 +HETATM 17 H17 RES A 444 19.89453 8.71684 -0.36839 H_ 1 0 0.05269 +HETATM 18 H18 RES A 444 17.72537 8.98355 0.21436 H___A 1 0 0.20964 +HETATM 19 C19 RES A 444 3.43963 14.29741 12.62221 C_3 4 0 0.03193 +HETATM 20 O20 RES A 444 3.07671 15.61822 12.23631 O_3 2 2 -0.39965 +HETATM 21 H21 RES A 444 4.27302 14.34187 13.32349 H_ 1 0 0.05269 +HETATM 22 H22 RES A 444 2.59308 13.81008 13.10508 H_ 1 0 0.05269 +HETATM 23 H23 RES A 444 3.73991 13.72415 11.74356 H_ 1 0 0.05269 +HETATM 24 H24 RES A 444 2.32966 15.52033 11.61130 H___A 1 0 0.20964 +HETATM 25 C25 RES A 444 16.06751 17.84957 14.39706 C_3 4 0 0.03193 +HETATM 26 O26 RES A 444 15.98970 19.07282 15.11734 O_3 2 2 -0.39965 +HETATM 27 H27 RES A 444 16.77526 17.18402 14.89204 H_ 1 0 0.05269 +HETATM 28 H28 RES A 444 15.08510 17.37867 14.36938 H_ 1 0 0.05269 +HETATM 29 H29 RES A 444 16.40684 18.04085 13.37809 H_ 1 0 0.05269 +HETATM 30 H30 RES A 444 15.35997 19.62900 14.61094 H___A 1 0 0.20964 +HETATM 31 C31 RES A 444 5.61540 13.90261 0.28024 C_3 4 0 0.03193 +HETATM 32 O32 RES A 444 6.96329 14.33980 0.39819 O_3 2 2 -0.39965 +HETATM 33 H33 RES A 444 5.39381 13.18200 1.06831 H_ 1 0 0.05269 +HETATM 34 H34 RES A 444 4.93854 14.75467 0.36989 H_ 1 0 0.05269 +HETATM 35 H35 RES A 444 5.46825 13.42632 -0.68848 H_ 1 0 0.05269 +HETATM 36 H36 RES A 444 7.08381 14.99923 -0.31851 H___A 1 0 0.20964 +HETATM 37 C37 RES A 444 10.38444 13.74977 1.74423 C_3 4 0 0.03193 +HETATM 38 O38 RES A 444 10.34865 13.00890 2.96031 O_3 2 2 -0.39965 +HETATM 39 H39 RES A 444 11.31498 14.30998 1.68756 H_ 1 0 0.05269 +HETATM 40 H40 RES A 444 10.32135 13.06875 0.89580 H_ 1 0 0.05269 +HETATM 41 H41 RES A 444 9.54190 14.44190 1.71309 H_ 1 0 0.05269 +HETATM 42 H42 RES A 444 9.45315 12.60486 2.98815 H___A 1 0 0.20964 +HETATM 43 C43 RES A 444 2.71877 -0.19852 13.91482 C_3 4 0 0.03193 +HETATM 44 O44 RES A 444 2.55981 1.00656 13.16980 O_3 2 2 -0.39965 +HETATM 45 H45 RES A 444 3.42887 -0.85053 13.40421 H_ 1 0 0.05269 +HETATM 46 H46 RES A 444 3.09835 0.02977 14.91227 H_ 1 0 0.05269 +HETATM 47 H47 RES A 444 1.76062 -0.71177 13.99933 H_ 1 0 0.05269 +HETATM 48 H48 RES A 444 1.92580 1.55260 13.68058 H___A 1 0 0.20964 +HETATM 49 C49 RES A 444 12.86271 12.87291 9.10254 C_3 4 0 0.03193 +HETATM 50 O50 RES A 444 12.72964 12.19590 7.85730 O_3 2 2 -0.39965 +HETATM 51 H51 RES A 444 11.91715 12.83126 9.64447 H_ 1 0 0.05269 +HETATM 52 H52 RES A 444 13.63913 12.39659 9.70188 H_ 1 0 0.05269 +HETATM 53 H53 RES A 444 13.12955 13.91577 8.92585 H_ 1 0 0.05269 +HETATM 54 H54 RES A 444 13.60640 12.28637 7.42000 H___A 1 0 0.20964 +HETATM 55 C55 RES A 444 0.91345 1.84436 7.21758 C_3 4 0 0.03193 +HETATM 56 O56 RES A 444 0.16704 0.83109 7.88260 O_3 2 2 -0.39965 +HETATM 57 H57 RES A 444 1.73149 1.39473 6.65448 H_ 1 0 0.05269 +HETATM 58 H58 RES A 444 0.25949 2.38287 6.53090 H_ 1 0 0.05269 +HETATM 59 H59 RES A 444 1.31674 2.54212 7.95173 H_ 1 0 0.05269 +HETATM 60 H60 RES A 444 0.79209 0.41480 8.51642 H___A 1 0 0.20964 +HETATM 61 C61 RES A 444 3.28235 16.40235 6.34784 C_3 4 0 0.03193 +HETATM 62 O62 RES A 444 4.40446 15.86811 5.64397 O_3 2 2 -0.39965 +HETATM 63 H63 RES A 444 3.52775 16.47384 7.40940 H_ 1 0 0.05269 +HETATM 64 H64 RES A 444 3.04852 17.39543 5.96551 H_ 1 0 0.05269 +HETATM 65 H65 RES A 444 2.41989 15.75077 6.22278 H_ 1 0 0.05269 +HETATM 66 H66 RES A 444 4.15040 15.88018 4.69552 H___A 1 0 0.20964 +HETATM 67 C67 RES A 444 14.28685 11.84833 2.69644 C_3 4 0 0.03193 +HETATM 68 O68 RES A 444 14.47540 12.00775 4.09802 O_3 2 2 -0.39965 +HETATM 69 H69 RES A 444 15.22519 11.52503 2.24449 H_ 1 0 0.05269 +HETATM 70 H70 RES A 444 13.51978 11.09713 2.50925 H_ 1 0 0.05269 +HETATM 71 H71 RES A 444 13.98187 12.79680 2.25228 H_ 1 0 0.05269 +HETATM 72 H72 RES A 444 13.60420 12.29868 4.44979 H___A 1 0 0.20964 +HETATM 73 C73 RES A 444 3.74650 0.37490 9.28202 C_3 4 0 0.03193 +HETATM 74 O74 RES A 444 4.68624 1.26369 8.68537 O_3 2 2 -0.39965 +HETATM 75 H75 RES A 444 4.28178 -0.38700 9.84868 H_ 1 0 0.05269 +HETATM 76 H76 RES A 444 3.08874 0.92642 9.95440 H_ 1 0 0.05269 +HETATM 77 H77 RES A 444 3.15691 -0.10643 8.50276 H_ 1 0 0.05269 +HETATM 78 H78 RES A 444 4.15269 1.92251 8.18619 H___A 1 0 0.20964 +HETATM 79 C79 RES A 444 17.93191 1.98830 17.28592 C_3 4 0 0.03193 +HETATM 80 O80 RES A 444 16.68990 1.36769 17.60090 O_3 2 2 -0.39965 +HETATM 81 H81 RES A 444 18.23740 2.63433 18.10865 H_ 1 0 0.05269 +HETATM 82 H82 RES A 444 18.69345 1.22519 17.12938 H_ 1 0 0.05269 +HETATM 83 H83 RES A 444 17.82727 2.59026 16.38313 H_ 1 0 0.05269 +HETATM 84 H84 RES A 444 16.45659 0.83462 16.81232 H___A 1 0 0.20964 +HETATM 85 C85 RES A 444 4.61466 10.52979 17.10957 C_3 4 0 0.03193 +HETATM 86 O86 RES A 444 3.62035 11.42538 17.60198 O_3 2 2 -0.39965 +HETATM 87 H87 RES A 444 5.60177 10.98718 17.19552 H_ 1 0 0.05269 +HETATM 88 H88 RES A 444 4.60514 9.60666 17.68872 H_ 1 0 0.05269 +HETATM 89 H89 RES A 444 4.42040 10.30112 16.06086 H_ 1 0 0.05269 +HETATM 90 H90 RES A 444 2.76200 10.96432 17.46823 H___A 1 0 0.20964 +HETATM 91 C91 RES A 444 4.21479 2.76452 1.93621 C_3 4 0 0.03193 +HETATM 92 O92 RES A 444 3.45640 2.43822 3.09183 O_3 2 2 -0.39965 +HETATM 93 H93 RES A 444 5.15561 3.22498 2.23935 H_ 1 0 0.05269 +HETATM 94 H94 RES A 444 4.42333 1.85922 1.36296 H_ 1 0 0.05269 +HETATM 95 H95 RES A 444 3.65868 3.46500 1.31342 H_ 1 0 0.05269 +HETATM 96 H96 RES A 444 2.68968 1.92747 2.75853 H___A 1 0 0.20964 +HETATM 97 C97 RES A 444 2.10781 10.76856 1.36312 C_3 4 0 0.03193 +HETATM 98 O98 RES A 444 0.80698 11.27394 1.07892 O_3 2 2 -0.39965 +HETATM 99 H99 RES A 444 2.85114 11.53660 1.14272 H_ 1 0 0.05269 +HETATM 100 H100 RES A 444 2.17873 10.49350 2.41651 H_ 1 0 0.05269 +HETATM 101 H101 RES A 444 2.31220 9.89096 0.74802 H_ 1 0 0.05269 +HETATM 102 H102 RES A 444 0.18009 10.55168 1.30975 H___A 1 0 0.20964 +HETATM 103 C103 RES A 444 16.26093 8.92927 6.57643 C_3 4 0 0.03193 +HETATM 104 O104 RES A 444 15.77968 8.06983 7.60177 O_3 2 2 -0.39965 +HETATM 105 H105 RES A 444 17.30509 9.17300 6.76897 H_ 1 0 0.05269 +HETATM 106 H106 RES A 444 16.18069 8.42876 5.61195 H_ 1 0 0.05269 +HETATM 107 H107 RES A 444 15.67380 9.84869 6.55835 H_ 1 0 0.05269 +HETATM 108 H108 RES A 444 14.84042 7.91008 7.37720 H___A 1 0 0.20964 +HETATM 109 C109 RES A 444 17.80004 2.06792 1.87371 C_3 4 0 0.03193 +HETATM 110 O110 RES A 444 18.48862 0.99081 1.24012 O_3 2 2 -0.39965 +HETATM 111 H111 RES A 444 18.23871 2.25534 2.85453 H_ 1 0 0.05269 +HETATM 112 H112 RES A 444 17.87937 2.96817 1.26859 H_ 1 0 0.05269 +HETATM 113 H113 RES A 444 16.74643 1.80633 1.99693 H_ 1 0 0.05269 +HETATM 114 H114 RES A 444 18.02202 0.85350 0.38356 H___A 1 0 0.20964 +HETATM 115 C115 RES A 444 13.75521 14.57173 15.42181 C_3 4 0 0.03193 +HETATM 116 O116 RES A 444 12.73183 15.48504 15.80455 O_3 2 2 -0.39965 +HETATM 117 H117 RES A 444 14.51862 14.53760 16.20019 H_ 1 0 0.05269 +HETATM 118 H118 RES A 444 13.33164 13.57618 15.29114 H_ 1 0 0.05269 +HETATM 119 H119 RES A 444 14.21175 14.89091 14.48437 H_ 1 0 0.05269 +HETATM 120 H120 RES A 444 12.11746 15.52768 15.03694 H___A 1 0 0.20964 +HETATM 121 C121 RES A 444 6.22569 16.46321 11.49168 C_3 4 0 0.03193 +HETATM 122 O122 RES A 444 7.37834 15.65849 11.27192 O_3 2 2 -0.39965 +HETATM 123 H123 RES A 444 6.47325 17.50688 11.31115 H_ 1 0 0.05269 +HETATM 124 H124 RES A 444 5.42639 16.16714 10.80967 H_ 1 0 0.05269 +HETATM 125 H125 RES A 444 5.88670 16.35324 12.52283 H_ 1 0 0.05269 +HETATM 126 H126 RES A 444 7.09224 14.73066 11.41776 H___A 1 0 0.20964 +HETATM 127 C127 RES A 444 20.01012 9.33317 4.86657 C_3 4 0 0.03193 +HETATM 128 O128 RES A 444 19.63827 8.14994 5.56401 O_3 2 2 -0.39965 +HETATM 129 H129 RES A 444 20.82510 9.82112 5.40128 H_ 1 0 0.05269 +HETATM 130 H130 RES A 444 20.34186 9.07963 3.85908 H_ 1 0 0.05269 +HETATM 131 H131 RES A 444 19.16051 10.01349 4.80673 H_ 1 0 0.05269 +HETATM 132 H132 RES A 444 18.86130 7.79949 5.07585 H___A 1 0 0.20964 +HETATM 133 C133 RES A 444 5.99486 1.97634 5.72513 C_3 4 0 0.03193 +HETATM 134 O134 RES A 444 6.74021 3.13466 6.08586 O_3 2 2 -0.39965 +HETATM 135 H135 RES A 444 4.92875 2.19578 5.79288 H_ 1 0 0.05269 +HETATM 136 H136 RES A 444 6.23376 1.68432 4.70221 H_ 1 0 0.05269 +HETATM 137 H137 RES A 444 6.23815 1.15441 6.40034 H_ 1 0 0.05269 +HETATM 138 H138 RES A 444 7.67684 2.83917 6.07790 H___A 1 0 0.20964 +HETATM 139 C139 RES A 444 13.03835 7.12913 5.28770 C_3 4 0 0.03193 +HETATM 140 O140 RES A 444 13.02644 7.55487 6.64544 O_3 2 2 -0.39965 +HETATM 141 H141 RES A 444 12.06949 6.70203 5.02747 H_ 1 0 0.05269 +HETATM 142 H142 RES A 444 13.24117 7.98172 4.63978 H_ 1 0 0.05269 +HETATM 143 H143 RES A 444 13.81531 6.37647 5.14697 H_ 1 0 0.05269 +HETATM 144 H144 RES A 444 12.38966 8.29858 6.65964 H___A 1 0 0.20964 +HETATM 145 C145 RES A 444 10.64649 1.42163 6.99575 C_3 4 0 0.03193 +HETATM 146 O146 RES A 444 11.32932 1.55767 8.23581 O_3 2 2 -0.39965 +HETATM 147 H147 RES A 444 9.77461 0.78340 7.13967 H_ 1 0 0.05269 +HETATM 148 H148 RES A 444 10.32031 2.40213 6.64261 H_ 1 0 0.05269 +HETATM 149 H149 RES A 444 11.30461 0.96891 6.25436 H_ 1 0 0.05269 +HETATM 150 H150 RES A 444 12.13048 2.09412 8.04749 H___A 1 0 0.20964 +HETATM 151 C151 RES A 444 7.70974 10.56643 0.43745 C_3 4 0 0.03193 +HETATM 152 O152 RES A 444 6.69643 10.25499 1.38817 O_3 2 2 -0.39965 +HETATM 153 H153 RES A 444 8.59868 10.91732 0.96199 H_ 1 0 0.05269 +HETATM 154 H154 RES A 444 7.96121 9.67471 -0.13665 H_ 1 0 0.05269 +HETATM 155 H155 RES A 444 7.36428 11.34806 -0.24011 H_ 1 0 0.05269 +HETATM 156 H156 RES A 444 5.94241 9.89154 0.87302 H___A 1 0 0.20964 +HETATM 157 C157 RES A 444 12.78344 1.18067 14.16301 C_3 4 0 0.03193 +HETATM 158 O158 RES A 444 14.01647 1.62010 13.60417 O_3 2 2 -0.39965 +HETATM 159 H159 RES A 444 12.98217 0.47776 14.97222 H_ 1 0 0.05269 +HETATM 160 H160 RES A 444 12.23227 2.03435 14.55662 H_ 1 0 0.05269 +HETATM 161 H161 RES A 444 12.18352 0.68832 13.39874 H_ 1 0 0.05269 +HETATM 162 H162 RES A 444 13.77530 2.26070 12.89474 H___A 1 0 0.20964 +HETATM 163 C163 RES A 444 16.94139 17.42253 1.05686 C_3 4 0 0.03193 +HETATM 164 O164 RES A 444 16.08424 16.29569 1.04946 O_3 2 2 -0.39965 +HETATM 165 H165 RES A 444 17.18791 17.69368 0.02960 H_ 1 0 0.05269 +HETATM 166 H166 RES A 444 16.43795 18.25970 1.54236 H_ 1 0 0.05269 +HETATM 167 H167 RES A 444 17.85566 17.18021 1.60025 H_ 1 0 0.05269 +HETATM 168 H168 RES A 444 15.85827 16.14412 1.99459 H___A 1 0 0.20964 +HETATM 169 C169 RES A 444 12.48878 18.07306 2.58158 C_3 4 0 0.03193 +HETATM 170 O170 RES A 444 13.76343 18.70451 2.65479 O_3 2 2 -0.39965 +HETATM 171 H171 RES A 444 12.02971 18.30966 1.62310 H_ 1 0 0.05269 +HETATM 172 H172 RES A 444 12.61189 16.99304 2.67149 H_ 1 0 0.05269 +HETATM 173 H173 RES A 444 11.85062 18.43623 3.38623 H_ 1 0 0.05269 +HETATM 174 H174 RES A 444 14.05960 18.54980 3.57438 H___A 1 0 0.20964 +HETATM 175 C175 RES A 444 19.92937 14.32320 3.09954 C_3 4 0 0.03193 +HETATM 176 O176 RES A 444 20.47921 14.98239 4.23349 O_3 2 2 -0.39965 +HETATM 177 H177 RES A 444 19.06424 14.88021 2.74247 H_ 1 0 0.05269 +HETATM 178 H178 RES A 444 20.67424 14.26863 2.30532 H_ 1 0 0.05269 +HETATM 179 H179 RES A 444 19.62003 13.31457 3.37662 H_ 1 0 0.05269 +HETATM 180 H180 RES A 444 21.24382 14.42340 4.50083 H___A 1 0 0.20964 +HETATM 181 C181 RES A 444 10.63009 10.62036 5.48247 C_3 4 0 0.03193 +HETATM 182 O182 RES A 444 11.32080 9.96459 6.53930 O_3 2 2 -0.39965 +HETATM 183 H183 RES A 444 9.97896 9.90801 4.97371 H_ 1 0 0.05269 +HETATM 184 H184 RES A 444 10.02580 11.43533 5.88411 H_ 1 0 0.05269 +HETATM 185 H185 RES A 444 11.34799 11.02578 4.76860 H_ 1 0 0.05269 +HETATM 186 H186 RES A 444 11.85790 10.67095 6.95281 H___A 1 0 0.20964 +HETATM 187 C187 RES A 444 15.65699 9.09727 17.99408 C_3 4 0 0.03193 +HETATM 188 O188 RES A 444 16.90142 9.78939 17.98916 O_3 2 2 -0.39965 +HETATM 189 H189 RES A 444 15.04412 9.44428 18.82685 H_ 1 0 0.05269 +HETATM 190 H190 RES A 444 15.12611 9.28242 17.05809 H_ 1 0 0.05269 +HETATM 191 H191 RES A 444 15.82887 8.02576 18.10423 H_ 1 0 0.05269 +HETATM 192 H192 RES A 444 17.40700 9.38003 17.24481 H___A 1 0 0.20964 +HETATM 193 C193 RES A 444 17.18063 5.09511 5.97377 C_3 4 0 0.03193 +HETATM 194 O194 RES A 444 17.00699 3.69621 6.16625 O_3 2 2 -0.39965 +HETATM 195 H195 RES A 444 16.80087 5.38050 4.99222 H_ 1 0 0.05269 +HETATM 196 H196 RES A 444 16.63290 5.63866 6.74297 H_ 1 0 0.05269 +HETATM 197 H197 RES A 444 18.23947 5.34654 6.03632 H_ 1 0 0.05269 +HETATM 198 H198 RES A 444 17.37922 3.51369 7.05728 H___A 1 0 0.20964 +HETATM 199 C199 RES A 444 9.27176 16.96360 18.60348 C_3 4 0 0.03193 +HETATM 200 O200 RES A 444 10.16048 17.88001 19.23027 O_3 2 2 -0.39965 +HETATM 201 H201 RES A 444 8.24372 17.25233 18.82182 H_ 1 0 0.05269 +HETATM 202 H202 RES A 444 9.42846 16.97594 17.52377 H_ 1 0 0.05269 +HETATM 203 H203 RES A 444 9.45162 15.95835 18.98512 H_ 1 0 0.05269 +HETATM 204 H204 RES A 444 11.05433 17.57777 18.98374 H___A 1 0 0.20964 +HETATM 205 C205 RES A 444 19.02698 11.32629 8.74382 C_3 4 0 0.03193 +HETATM 206 O206 RES A 444 19.55395 11.57496 7.44476 O_3 2 2 -0.39965 +HETATM 207 H207 RES A 444 19.84306 11.28874 9.46486 H_ 1 0 0.05269 +HETATM 208 H208 RES A 444 18.34041 12.12651 9.02172 H_ 1 0 0.05269 +HETATM 209 H209 RES A 444 18.49941 10.37268 8.75573 H_ 1 0 0.05269 +HETATM 210 H210 RES A 444 18.77484 11.55877 6.84653 H___A 1 0 0.20964 +HETATM 211 C211 RES A 444 13.70984 17.91381 18.18096 C_3 4 0 0.03193 +HETATM 212 O212 RES A 444 12.78082 16.86629 18.42949 O_3 2 2 -0.39965 +HETATM 213 H213 RES A 444 14.65264 17.49419 17.82801 H_ 1 0 0.05269 +HETATM 214 H214 RES A 444 13.30579 18.58561 17.42320 H_ 1 0 0.05269 +HETATM 215 H215 RES A 444 13.88737 18.47185 19.10049 H_ 1 0 0.05269 +HETATM 216 H216 RES A 444 12.70938 16.39241 17.57615 H___A 1 0 0.20964 +HETATM 217 C217 RES A 444 7.96084 1.88854 9.90132 C_3 4 0 0.03193 +HETATM 218 O218 RES A 444 7.16836 0.76877 10.27166 O_3 2 2 -0.39965 +HETATM 219 H219 RES A 444 8.08701 1.90679 8.82000 H_ 1 0 0.05269 +HETATM 220 H220 RES A 444 7.47244 2.80930 10.22050 H_ 1 0 0.05269 +HETATM 221 H221 RES A 444 8.93667 1.81039 10.37952 H_ 1 0 0.05269 +HETATM 222 H222 RES A 444 6.33219 0.87991 9.77220 H___A 1 0 0.20964 +HETATM 223 C223 RES A 444 8.67989 16.70958 5.83790 C_3 4 0 0.03193 +HETATM 224 O224 RES A 444 8.12024 17.60224 6.79460 O_3 2 2 -0.39965 +HETATM 225 H225 RES A 444 8.09228 16.75013 4.91967 H_ 1 0 0.05269 +HETATM 226 H226 RES A 444 9.70728 17.00048 5.62151 H_ 1 0 0.05269 +HETATM 227 H227 RES A 444 8.66415 15.69153 6.22812 H_ 1 0 0.05269 +HETATM 228 H228 RES A 444 8.61953 17.44038 7.62546 H___A 1 0 0.20964 +HETATM 229 C229 RES A 444 8.92912 4.00904 0.50900 C_3 4 0 0.03193 +HETATM 230 O230 RES A 444 8.96759 5.27857 -0.13058 O_3 2 2 -0.39965 +HETATM 231 H231 RES A 444 8.33969 4.08141 1.42278 H_ 1 0 0.05269 +HETATM 232 H232 RES A 444 8.47682 3.27429 -0.15833 H_ 1 0 0.05269 +HETATM 233 H233 RES A 444 9.94193 3.69036 0.75961 H_ 1 0 0.05269 +HETATM 234 H234 RES A 444 9.53405 5.14064 -0.92363 H___A 1 0 0.20964 +HETATM 235 C235 RES A 444 14.12006 6.78048 11.59632 C_3 4 0 0.03193 +HETATM 236 O236 RES A 444 13.07688 7.13628 10.69542 O_3 2 2 -0.39965 +HETATM 237 H237 RES A 444 14.86068 7.57932 11.63302 H_ 1 0 0.05269 +HETATM 238 H238 RES A 444 13.70582 6.62813 12.59405 H_ 1 0 0.05269 +HETATM 239 H239 RES A 444 14.60290 5.86276 11.26001 H_ 1 0 0.05269 +HETATM 240 H240 RES A 444 12.46641 6.36815 10.68540 H___A 1 0 0.20964 +HETATM 241 C241 RES A 444 11.17366 12.60541 17.35410 C_3 4 0 0.03193 +HETATM 242 O242 RES A 444 11.02139 13.96786 17.73395 O_3 2 2 -0.39965 +HETATM 243 H243 RES A 444 10.47704 11.99021 17.92352 H_ 1 0 0.05269 +HETATM 244 H244 RES A 444 10.96097 12.49402 16.29011 H_ 1 0 0.05269 +HETATM 245 H245 RES A 444 12.19388 12.27752 17.55780 H_ 1 0 0.05269 +HETATM 246 H246 RES A 444 11.62997 14.46572 17.15437 H___A 1 0 0.20964 +HETATM 247 C247 RES A 444 13.59375 17.68257 6.60725 C_3 4 0 0.03193 +HETATM 248 O248 RES A 444 14.41796 18.19915 5.56896 O_3 2 2 -0.39965 +HETATM 249 H249 RES A 444 12.56750 17.59958 6.25257 H_ 1 0 0.05269 +HETATM 250 H250 RES A 444 13.95140 16.69610 6.90350 H_ 1 0 0.05269 +HETATM 251 H251 RES A 444 13.62441 18.35441 7.46523 H_ 1 0 0.05269 +HETATM 252 H252 RES A 444 15.31701 18.26489 5.96089 H___A 1 0 0.20964 +HETATM 253 C253 RES A 444 5.00550 8.70879 7.93082 C_3 4 0 0.03193 +HETATM 254 O254 RES A 444 5.30633 7.53730 7.17920 O_3 2 2 -0.39965 +HETATM 255 H255 RES A 444 3.92410 8.80228 8.03546 H_ 1 0 0.05269 +HETATM 256 H256 RES A 444 5.45973 8.64206 8.92134 H_ 1 0 0.05269 +HETATM 257 H257 RES A 444 5.39337 9.58812 7.41497 H_ 1 0 0.05269 +HETATM 258 H258 RES A 444 6.28240 7.52607 7.08649 H___A 1 0 0.20964 +HETATM 259 C259 RES A 444 19.22046 1.28969 13.91270 C_3 4 0 0.03193 +HETATM 260 O260 RES A 444 20.08805 2.12898 14.66921 O_3 2 2 -0.39965 +HETATM 261 H261 RES A 444 18.36269 1.87059 13.57299 H_ 1 0 0.05269 +HETATM 262 H262 RES A 444 19.74873 0.89208 13.04541 H_ 1 0 0.05269 +HETATM 263 H263 RES A 444 18.87095 0.46148 14.53042 H_ 1 0 0.05269 +HETATM 264 H264 RES A 444 20.73583 1.52580 15.09558 H___A 1 0 0.20964 +HETATM 265 C265 RES A 444 5.65052 5.42047 10.40141 C_3 4 0 0.03193 +HETATM 266 O266 RES A 444 6.43233 5.15576 11.55959 O_3 2 2 -0.39965 +HETATM 267 H267 RES A 444 4.77591 4.76790 10.40245 H_ 1 0 0.05269 +HETATM 268 H268 RES A 444 5.31750 6.45945 10.40208 H_ 1 0 0.05269 +HETATM 269 H269 RES A 444 6.23775 5.22771 9.50311 H_ 1 0 0.05269 +HETATM 270 H270 RES A 444 7.22334 5.73649 11.49818 H___A 1 0 0.20964 +HETATM 271 C271 RES A 444 13.28289 5.81639 20.26495 C_3 4 0 0.03193 +HETATM 272 O272 RES A 444 14.46108 5.91020 19.47306 O_3 2 2 -0.39965 +HETATM 273 H273 RES A 444 12.54449 6.53149 19.89956 H_ 1 0 0.05269 +HETATM 274 H274 RES A 444 12.86565 4.81041 20.20085 H_ 1 0 0.05269 +HETATM 275 H275 RES A 444 13.51599 6.04282 21.30628 H_ 1 0 0.05269 +HETATM 276 H276 RES A 444 15.06689 5.21681 19.82048 H___A 1 0 0.20964 +HETATM 277 C277 RES A 444 8.93119 18.18764 13.28407 C_3 4 0 0.03193 +HETATM 278 O278 RES A 444 7.83369 17.94987 14.15258 O_3 2 2 -0.39965 +HETATM 279 H279 RES A 444 8.62256 18.85058 12.47662 H_ 1 0 0.05269 +HETATM 280 H280 RES A 444 9.74951 18.65521 13.83984 H_ 1 0 0.05269 +HETATM 281 H281 RES A 444 9.27914 17.24313 12.85839 H_ 1 0 0.05269 +HETATM 282 H282 RES A 444 8.18034 17.33710 14.83873 H___A 1 0 0.20964 +HETATM 283 C283 RES A 444 5.79456 2.19968 17.80701 C_3 4 0 0.03193 +HETATM 284 O284 RES A 444 6.24133 2.96696 16.69489 O_3 2 2 -0.39965 +HETATM 285 H285 RES A 444 5.95925 2.76662 18.72146 H_ 1 0 0.05269 +HETATM 286 H286 RES A 444 4.73133 1.97951 17.70368 H_ 1 0 0.05269 +HETATM 287 H287 RES A 444 6.35360 1.26369 17.85787 H_ 1 0 0.05269 +HETATM 288 H288 RES A 444 6.11167 2.36984 15.93032 H___A 1 0 0.20964 +HETATM 289 C289 RES A 444 7.02257 8.31146 13.32419 C_3 4 0 0.03193 +HETATM 290 O290 RES A 444 6.81830 9.58617 13.92250 O_3 2 2 -0.39965 +HETATM 291 H291 RES A 444 6.70351 7.53159 14.01772 H_ 1 0 0.05269 +HETATM 292 H292 RES A 444 6.43819 8.23664 12.40602 H_ 1 0 0.05269 +HETATM 293 H293 RES A 444 8.08019 8.17829 13.09255 H_ 1 0 0.05269 +HETATM 294 H294 RES A 444 7.15181 10.23194 13.26245 H___A 1 0 0.20964 +HETATM 295 C295 RES A 444 14.02631 3.46938 16.96774 C_3 4 0 0.03193 +HETATM 296 O296 RES A 444 13.54366 2.24600 17.51611 O_3 2 2 -0.39965 +HETATM 297 H297 RES A 444 13.77498 3.53066 15.91013 H_ 1 0 0.05269 +HETATM 298 H298 RES A 444 13.56595 4.30739 17.48900 H_ 1 0 0.05269 +HETATM 299 H299 RES A 444 15.10861 3.52592 17.07904 H_ 1 0 0.05269 +HETATM 300 H300 RES A 444 13.94305 2.20406 18.41525 H___A 1 0 0.20964 +HETATM 301 C301 RES A 444 1.20831 18.57486 2.95108 C_3 4 0 0.03193 +HETATM 302 O302 RES A 444 1.22576 19.81993 2.26075 O_3 2 2 -0.39965 +HETATM 303 H303 RES A 444 0.55458 18.64320 3.82147 H_ 1 0 0.05269 +HETATM 304 H304 RES A 444 0.84728 17.78646 2.28798 H_ 1 0 0.05269 +HETATM 305 H305 RES A 444 2.21813 18.32995 3.28130 H_ 1 0 0.05269 +HETATM 306 H306 RES A 444 0.30364 19.97372 1.97883 H___A 1 0 0.20964 +HETATM 307 C307 RES A 444 13.27354 18.56828 10.67719 C_3 4 0 0.03193 +HETATM 308 O308 RES A 444 12.48821 17.54334 10.07841 O_3 2 2 -0.39965 +HETATM 309 H309 RES A 444 12.67535 19.47728 10.75867 H_ 1 0 0.05269 +HETATM 310 H310 RES A 444 13.59103 18.25289 11.67155 H_ 1 0 0.05269 +HETATM 311 H311 RES A 444 14.15208 18.77184 10.06448 H_ 1 0 0.05269 +HETATM 312 H312 RES A 444 13.09935 16.78781 9.93641 H___A 1 0 0.20964 +HETATM 313 C313 RES A 444 6.36730 14.29234 8.10345 C_3 4 0 0.03193 +HETATM 314 O314 RES A 444 6.40678 13.98673 6.71535 O_3 2 2 -0.39965 +HETATM 315 H315 RES A 444 5.36805 14.09806 8.49177 H_ 1 0 0.05269 +HETATM 316 H316 RES A 444 7.08832 13.66856 8.63166 H_ 1 0 0.05269 +HETATM 317 H317 RES A 444 6.61905 15.34196 8.25886 H_ 1 0 0.05269 +HETATM 318 H318 RES A 444 5.76587 14.60457 6.30951 H___A 1 0 0.20964 +HETATM 319 C319 RES A 444 2.65328 9.08063 11.58358 C_3 4 0 0.03193 +HETATM 320 O320 RES A 444 2.00217 9.04988 10.31818 O_3 2 2 -0.39965 +HETATM 321 H321 RES A 444 2.77179 8.06201 11.95511 H_ 1 0 0.05269 +HETATM 322 H322 RES A 444 3.63556 9.54427 11.48302 H_ 1 0 0.05269 +HETATM 323 H323 RES A 444 2.05382 9.65342 12.29226 H_ 1 0 0.05269 +HETATM 324 H324 RES A 444 1.90245 9.98881 10.05330 H___A 1 0 0.20964 +HETATM 325 C325 RES A 444 16.09537 13.47946 18.75299 C_3 4 0 0.03193 +HETATM 326 O326 RES A 444 15.35647 12.29789 19.02596 O_3 2 2 -0.39965 +HETATM 327 H327 RES A 444 15.44738 14.34606 18.88103 H_ 1 0 0.05269 +HETATM 328 H328 RES A 444 16.93959 13.54850 19.44072 H_ 1 0 0.05269 +HETATM 329 H329 RES A 444 16.46394 13.45617 17.72675 H_ 1 0 0.05269 +HETATM 330 H330 RES A 444 15.94172 11.56097 18.74998 H___A 1 0 0.20964 +HETATM 331 C331 RES A 444 5.36713 6.40841 19.02468 C_3 4 0 0.03193 +HETATM 332 O332 RES A 444 6.23337 6.92207 18.01801 O_3 2 2 -0.39965 +HETATM 333 H333 RES A 444 4.33549 6.65297 18.77623 H_ 1 0 0.05269 +HETATM 334 H334 RES A 444 5.47707 5.32425 19.08654 H_ 1 0 0.05269 +HETATM 335 H335 RES A 444 5.62819 6.85675 19.98559 H_ 1 0 0.05269 +HETATM 336 H336 RES A 444 7.13950 6.67949 18.31120 H___A 1 0 0.20964 +HETATM 337 C337 RES A 444 1.77513 13.81811 9.21198 C_3 4 0 0.03193 +HETATM 338 O338 RES A 444 0.83100 14.28966 10.16552 O_3 2 2 -0.39965 +HETATM 339 H339 RES A 444 1.29728 13.75593 8.23483 H_ 1 0 0.05269 +HETATM 340 H340 RES A 444 2.62178 14.50388 9.15673 H_ 1 0 0.05269 +HETATM 341 H341 RES A 444 2.12880 12.82836 9.50371 H_ 1 0 0.05269 +HETATM 342 H342 RES A 444 1.30194 14.30478 11.02173 H___A 1 0 0.20964 +HETATM 343 C343 RES A 444 21.59943 4.06368 17.75073 C_3 4 0 0.03193 +HETATM 344 O344 RES A 444 21.85233 3.04768 18.71336 O_3 2 2 -0.39965 +HETATM 345 H345 RES A 444 22.11092 3.81498 16.82008 H_ 1 0 0.05269 +HETATM 346 H346 RES A 444 20.52800 4.13659 17.56408 H_ 1 0 0.05269 +HETATM 347 H347 RES A 444 21.97071 5.01986 18.11886 H_ 1 0 0.05269 +HETATM 348 H348 RES A 444 21.40074 3.34325 19.53474 H___A 1 0 0.20964 +HETATM 349 C349 RES A 444 16.52622 4.73908 13.63762 C_3 4 0 0.03193 +HETATM 350 O350 RES A 444 15.55282 5.45454 14.38889 O_3 2 2 -0.39965 +HETATM 351 H351 RES A 444 16.03370 3.96708 13.04616 H_ 1 0 0.05269 +HETATM 352 H352 RES A 444 17.05262 5.42291 12.96909 H_ 1 0 0.05269 +HETATM 353 H353 RES A 444 17.24076 4.27126 14.31456 H_ 1 0 0.05269 +HETATM 354 H354 RES A 444 16.06701 6.07053 14.95693 H___A 1 0 0.20964 +HETATM 355 C355 RES A 444 20.20141 14.20302 18.50889 C_3 4 0 0.03193 +HETATM 356 O356 RES A 444 21.44729 13.78288 19.04009 O_3 2 2 -0.39965 +HETATM 357 H357 RES A 444 20.32931 15.13613 17.95996 H_ 1 0 0.05269 +HETATM 358 H358 RES A 444 19.81275 13.43791 17.83324 H_ 1 0 0.05269 +HETATM 359 H359 RES A 444 19.48848 14.36395 19.32079 H_ 1 0 0.05269 +HETATM 360 H360 RES A 444 21.25026 12.96615 19.54627 H___A 1 0 0.20964 +HETATM 361 C361 RES A 444 3.32298 14.94425 16.50422 C_3 4 0 0.03193 +HETATM 362 O362 RES A 444 4.38694 14.00670 16.37303 O_3 2 2 -0.39965 +HETATM 363 H363 RES A 444 3.54498 15.83135 15.91086 H_ 1 0 0.05269 +HETATM 364 H364 RES A 444 2.39143 14.50263 16.15017 H_ 1 0 0.05269 +HETATM 365 H365 RES A 444 3.21366 15.23418 17.54978 H_ 1 0 0.05269 +HETATM 366 H366 RES A 444 4.09659 13.20452 16.85511 H___A 1 0 0.20964 +HETATM 367 C367 RES A 444 10.00891 1.19780 16.80998 C_3 4 0 0.03193 +HETATM 368 O368 RES A 444 10.58951 1.67540 18.01757 O_3 2 2 -0.39965 +HETATM 369 H369 RES A 444 8.95573 0.97837 16.97853 H_ 1 0 0.05269 +HETATM 370 H370 RES A 444 10.09279 1.95889 16.03422 H_ 1 0 0.05269 +HETATM 371 H371 RES A 444 10.51430 0.28729 16.48583 H_ 1 0 0.05269 +HETATM 372 H372 RES A 444 11.54632 1.78202 17.83462 H___A 1 0 0.20964 +HETATM 373 C373 RES A 444 1.31776 5.21190 2.64974 C_3 4 0 0.03193 +HETATM 374 O374 RES A 444 0.78156 4.20400 1.79964 O_3 2 2 -0.39965 +HETATM 375 H375 RES A 444 2.00060 5.84322 2.08036 H_ 1 0 0.05269 +HETATM 376 H376 RES A 444 0.50993 5.82499 3.05018 H_ 1 0 0.05269 +HETATM 377 H377 RES A 444 1.85905 4.74873 3.47448 H_ 1 0 0.05269 +HETATM 378 H378 RES A 444 0.20631 3.65922 2.38482 H___A 1 0 0.20964 +HETATM 379 C379 RES A 444 5.74906 1.64126 13.27894 C_3 4 0 0.03193 +HETATM 380 O380 RES A 444 5.74933 0.96366 14.53304 O_3 2 2 -0.39965 +HETATM 381 H381 RES A 444 5.05775 2.48272 13.31880 H_ 1 0 0.05269 +HETATM 382 H382 RES A 444 6.74849 2.01315 13.05234 H_ 1 0 0.05269 +HETATM 383 H383 RES A 444 5.43187 0.95557 12.49248 H_ 1 0 0.05269 +HETATM 384 H384 RES A 444 6.42516 0.25912 14.43537 H___A 1 0 0.20964 +FORMAT CONECT (a6,12i6) +CONECT 1 2 3 4 5 +CONECT 2 1 6 +CONECT 3 1 +CONECT 4 1 +CONECT 5 1 +CONECT 6 2 +CONECT 7 8 9 10 11 +CONECT 8 7 12 +CONECT 9 7 +CONECT 10 7 +CONECT 11 7 +CONECT 12 8 +CONECT 13 14 15 16 17 +CONECT 14 13 18 +CONECT 15 13 +CONECT 16 13 +CONECT 17 13 +CONECT 18 14 +CONECT 19 20 21 22 23 +CONECT 20 19 24 +CONECT 21 19 +CONECT 22 19 +CONECT 23 19 +CONECT 24 20 +CONECT 25 26 27 28 29 +CONECT 26 25 30 +CONECT 27 25 +CONECT 28 25 +CONECT 29 25 +CONECT 30 26 +CONECT 31 32 33 34 35 +CONECT 32 31 36 +CONECT 33 31 +CONECT 34 31 +CONECT 35 31 +CONECT 36 32 +CONECT 37 38 39 40 41 +CONECT 38 37 42 +CONECT 39 37 +CONECT 40 37 +CONECT 41 37 +CONECT 42 38 +CONECT 43 44 45 46 47 +CONECT 44 43 48 +CONECT 45 43 +CONECT 46 43 +CONECT 47 43 +CONECT 48 44 +CONECT 49 50 51 52 53 +CONECT 50 49 54 +CONECT 51 49 +CONECT 52 49 +CONECT 53 49 +CONECT 54 50 +CONECT 55 56 57 58 59 +CONECT 56 55 60 +CONECT 57 55 +CONECT 58 55 +CONECT 59 55 +CONECT 60 56 +CONECT 61 62 63 64 65 +CONECT 62 61 66 +CONECT 63 61 +CONECT 64 61 +CONECT 65 61 +CONECT 66 62 +CONECT 67 68 69 70 71 +CONECT 68 67 72 +CONECT 69 67 +CONECT 70 67 +CONECT 71 67 +CONECT 72 68 +CONECT 73 74 75 76 77 +CONECT 74 73 78 +CONECT 75 73 +CONECT 76 73 +CONECT 77 73 +CONECT 78 74 +CONECT 79 80 81 82 83 +CONECT 80 79 84 +CONECT 81 79 +CONECT 82 79 +CONECT 83 79 +CONECT 84 80 +CONECT 85 86 87 88 89 +CONECT 86 85 90 +CONECT 87 85 +CONECT 88 85 +CONECT 89 85 +CONECT 90 86 +CONECT 91 92 93 94 95 +CONECT 92 91 96 +CONECT 93 91 +CONECT 94 91 +CONECT 95 91 +CONECT 96 92 +CONECT 97 98 99 100 101 +CONECT 98 97 102 +CONECT 99 97 +CONECT 100 97 +CONECT 101 97 +CONECT 102 98 +CONECT 103 104 105 106 107 +CONECT 104 103 108 +CONECT 105 103 +CONECT 106 103 +CONECT 107 103 +CONECT 108 104 +CONECT 109 110 111 112 113 +CONECT 110 109 114 +CONECT 111 109 +CONECT 112 109 +CONECT 113 109 +CONECT 114 110 +CONECT 115 116 117 118 119 +CONECT 116 115 120 +CONECT 117 115 +CONECT 118 115 +CONECT 119 115 +CONECT 120 116 +CONECT 121 122 123 124 125 +CONECT 122 121 126 +CONECT 123 121 +CONECT 124 121 +CONECT 125 121 +CONECT 126 122 +CONECT 127 128 129 130 131 +CONECT 128 127 132 +CONECT 129 127 +CONECT 130 127 +CONECT 131 127 +CONECT 132 128 +CONECT 133 134 135 136 137 +CONECT 134 133 138 +CONECT 135 133 +CONECT 136 133 +CONECT 137 133 +CONECT 138 134 +CONECT 139 140 141 142 143 +CONECT 140 139 144 +CONECT 141 139 +CONECT 142 139 +CONECT 143 139 +CONECT 144 140 +CONECT 145 146 147 148 149 +CONECT 146 145 150 +CONECT 147 145 +CONECT 148 145 +CONECT 149 145 +CONECT 150 146 +CONECT 151 152 153 154 155 +CONECT 152 151 156 +CONECT 153 151 +CONECT 154 151 +CONECT 155 151 +CONECT 156 152 +CONECT 157 158 159 160 161 +CONECT 158 157 162 +CONECT 159 157 +CONECT 160 157 +CONECT 161 157 +CONECT 162 158 +CONECT 163 164 165 166 167 +CONECT 164 163 168 +CONECT 165 163 +CONECT 166 163 +CONECT 167 163 +CONECT 168 164 +CONECT 169 170 171 172 173 +CONECT 170 169 174 +CONECT 171 169 +CONECT 172 169 +CONECT 173 169 +CONECT 174 170 +CONECT 175 176 177 178 179 +CONECT 176 175 180 +CONECT 177 175 +CONECT 178 175 +CONECT 179 175 +CONECT 180 176 +CONECT 181 182 183 184 185 +CONECT 182 181 186 +CONECT 183 181 +CONECT 184 181 +CONECT 185 181 +CONECT 186 182 +CONECT 187 188 189 190 191 +CONECT 188 187 192 +CONECT 189 187 +CONECT 190 187 +CONECT 191 187 +CONECT 192 188 +CONECT 193 194 195 196 197 +CONECT 194 193 198 +CONECT 195 193 +CONECT 196 193 +CONECT 197 193 +CONECT 198 194 +CONECT 199 200 201 202 203 +CONECT 200 199 204 +CONECT 201 199 +CONECT 202 199 +CONECT 203 199 +CONECT 204 200 +CONECT 205 206 207 208 209 +CONECT 206 205 210 +CONECT 207 205 +CONECT 208 205 +CONECT 209 205 +CONECT 210 206 +CONECT 211 212 213 214 215 +CONECT 212 211 216 +CONECT 213 211 +CONECT 214 211 +CONECT 215 211 +CONECT 216 212 +CONECT 217 218 219 220 221 +CONECT 218 217 222 +CONECT 219 217 +CONECT 220 217 +CONECT 221 217 +CONECT 222 218 +CONECT 223 224 225 226 227 +CONECT 224 223 228 +CONECT 225 223 +CONECT 226 223 +CONECT 227 223 +CONECT 228 224 +CONECT 229 230 231 232 233 +CONECT 230 229 234 +CONECT 231 229 +CONECT 232 229 +CONECT 233 229 +CONECT 234 230 +CONECT 235 236 237 238 239 +CONECT 236 235 240 +CONECT 237 235 +CONECT 238 235 +CONECT 239 235 +CONECT 240 236 +CONECT 241 242 243 244 245 +CONECT 242 241 246 +CONECT 243 241 +CONECT 244 241 +CONECT 245 241 +CONECT 246 242 +CONECT 247 248 249 250 251 +CONECT 248 247 252 +CONECT 249 247 +CONECT 250 247 +CONECT 251 247 +CONECT 252 248 +CONECT 253 254 255 256 257 +CONECT 254 253 258 +CONECT 255 253 +CONECT 256 253 +CONECT 257 253 +CONECT 258 254 +CONECT 259 260 261 262 263 +CONECT 260 259 264 +CONECT 261 259 +CONECT 262 259 +CONECT 263 259 +CONECT 264 260 +CONECT 265 266 267 268 269 +CONECT 266 265 270 +CONECT 267 265 +CONECT 268 265 +CONECT 269 265 +CONECT 270 266 +CONECT 271 272 273 274 275 +CONECT 272 271 276 +CONECT 273 271 +CONECT 274 271 +CONECT 275 271 +CONECT 276 272 +CONECT 277 278 279 280 281 +CONECT 278 277 282 +CONECT 279 277 +CONECT 280 277 +CONECT 281 277 +CONECT 282 278 +CONECT 283 284 285 286 287 +CONECT 284 283 288 +CONECT 285 283 +CONECT 286 283 +CONECT 287 283 +CONECT 288 284 +CONECT 289 290 291 292 293 +CONECT 290 289 294 +CONECT 291 289 +CONECT 292 289 +CONECT 293 289 +CONECT 294 290 +CONECT 295 296 297 298 299 +CONECT 296 295 300 +CONECT 297 295 +CONECT 298 295 +CONECT 299 295 +CONECT 300 296 +CONECT 301 302 303 304 305 +CONECT 302 301 306 +CONECT 303 301 +CONECT 304 301 +CONECT 305 301 +CONECT 306 302 +CONECT 307 308 309 310 311 +CONECT 308 307 312 +CONECT 309 307 +CONECT 310 307 +CONECT 311 307 +CONECT 312 308 +CONECT 313 314 315 316 317 +CONECT 314 313 318 +CONECT 315 313 +CONECT 316 313 +CONECT 317 313 +CONECT 318 314 +CONECT 319 320 321 322 323 +CONECT 320 319 324 +CONECT 321 319 +CONECT 322 319 +CONECT 323 319 +CONECT 324 320 +CONECT 325 326 327 328 329 +CONECT 326 325 330 +CONECT 327 325 +CONECT 328 325 +CONECT 329 325 +CONECT 330 326 +CONECT 331 332 333 334 335 +CONECT 332 331 336 +CONECT 333 331 +CONECT 334 331 +CONECT 335 331 +CONECT 336 332 +CONECT 337 338 339 340 341 +CONECT 338 337 342 +CONECT 339 337 +CONECT 340 337 +CONECT 341 337 +CONECT 342 338 +CONECT 343 344 345 346 347 +CONECT 344 343 348 +CONECT 345 343 +CONECT 346 343 +CONECT 347 343 +CONECT 348 344 +CONECT 349 350 351 352 353 +CONECT 350 349 354 +CONECT 351 349 +CONECT 352 349 +CONECT 353 349 +CONECT 354 350 +CONECT 355 356 357 358 359 +CONECT 356 355 360 +CONECT 357 355 +CONECT 358 355 +CONECT 359 355 +CONECT 360 356 +CONECT 361 362 363 364 365 +CONECT 362 361 366 +CONECT 363 361 +CONECT 364 361 +CONECT 365 361 +CONECT 366 362 +CONECT 367 368 369 370 371 +CONECT 368 367 372 +CONECT 369 367 +CONECT 370 367 +CONECT 371 367 +CONECT 372 368 +CONECT 373 374 375 376 377 +CONECT 374 373 378 +CONECT 375 373 +CONECT 376 373 +CONECT 377 373 +CONECT 378 374 +CONECT 379 380 381 382 383 +CONECT 380 379 384 +CONECT 381 379 +CONECT 382 379 +CONECT 383 379 +CONECT 384 380 +END diff --git a/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat new file mode 100644 index 0000000000..b856598735 --- /dev/null +++ b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat @@ -0,0 +1,56 @@ +Energy expression created for 3D-periodic boundary conditions. + Cell information: + Density (g/cc): 0.4573 + Volume (A**3): 7447.2363 + A: 19.9969 Alpha: 90.0000 + B: 19.1282 Beta : 90.0000 + C: 19.4697 Gamma: 90.0000 + + Summary of the energy expression: + Movable atoms : 384 Fixed atoms : 0 + Polar atoms : 0 + Bonds : 320 Angles : 448 + Torsions : 192 Inversions : 0 + Urey-Bradley : 0 Bend-bend : 0 + Stretch-stretch : 0 Sep-stretch-stretch : 0 + Stretch-bend-stretch : 0 Torsion-stretch : 0 + Torsion-bend-bend : 0 Stretch-torsion-stretch: 0 + Bend-torsion-bend : 0 + Hydrogen-bond acceptors: 64 Hydrogen-bond donors : 64 + Nonbond exclusions : 768 Polar-polar exclusions : 0 + + Total charge : -0.001 Movable atoms only : -0.001 + Total mass : 2050.688 Movable atoms only : 2050.688 + +Automatically calculating Ewald parameters for Coulomb sum. + +Summary of Non-bond set up :- + Non-bond list cutoff radius : 13.530 (A) + Number of non-bond terms in list : 101788 + This has been updated 1 times since the energy expression was created. + + Using Ewald sums for Coulomb terms with: + Eta=3.932, Rcut=11.530, Kcut=0.298, Acc.=0.001 + +VDW terms truncated at : 8.500 (A) + +Diagonal VdW parameters combined using the arithmetic combination rule. + +Summary of H-bond set up using a h-bond list. + +There are 604 interactions within hbond cutoffs of + Donor-acceptor distances less than 6.500 (A) and + Donor-h-acceptor angles greater than 90.000 (degrees) + +************************************************************************ + Energy Decomposition + Valence Terms Nonbond Terms + Bonds : 0.535675 Van der Waals : -56.0592 + Angles : 1.28188 Electrostatic : 234.036 + Torsions : 1.23250 Hydrogen Bonds: -68.7337 + Inversions : 0.000000E+00 Restraints : 0.000000E+00 + Urey-Bradley : 0.000000E+00 3-Body : 0.000000E+00 + Cross-Terms : 0.000000E+00 + Total Energy : 112.293 +************************************************************************ + diff --git a/examples/dreiding/data.dreiding b/examples/dreiding/data.dreiding new file mode 100644 index 0000000000..f6d9bcf22d --- /dev/null +++ b/examples/dreiding/data.dreiding @@ -0,0 +1,1400 @@ +Created on Mon Oct 3 10:06:14 2011 + + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + + 4 atom types + 3 bond types + 2 angle types + 1 dihedral types + 0 improper types + + 0.000000 19.996890 xlo xhi + 0.000000 19.128160 ylo yhi + 0.000000 19.469710 zlo zhi + +Masses + + 1 1.0080 # H_ + 2 1.0080 # H___A + 3 12.0110 # C_3 + 4 15.9994 # O_3 + + +Bond Coeffs + + 1 350 1.42 # O_3 C_3 + 2 350 0.98 # O_3 H___A + 3 350 1.09 # C_3 H_ + +Angle Coeffs + + 1 50 104.51 # X O_3 X + 2 50 109.471 # X C_3 X + +Dihedral Coeffs + + 1 0.333333 1 3 # X O_3 C_3 X + +Atoms + + 1 444 3 0.03193 9.75768 9.43603 9.44978 0 0 0 + 2 444 4 -0.39965 9.07001 9.89252 10.61030 0 0 0 + 3 444 1 0.05269 9.56169 8.37372 9.30573 0 0 0 + 4 444 1 0.05269 9.40633 9.98872 8.57739 0 0 0 + 5 444 1 0.05269 10.83081 9.58873 9.56849 0 0 0 + 6 444 2 0.20964 9.28861 10.84826 10.67569 0 0 0 + 7 444 3 0.03193 7.87790 6.57305 4.37926 0 0 0 + 8 444 4 -0.39965 9.21046 6.55811 3.88167 0 0 0 + 9 444 1 0.05269 7.42565 7.54437 4.17519 0 0 0 + 10 444 1 0.05269 7.28908 5.79550 3.89029 0 0 0 + 11 444 1 0.05269 7.88159 6.39628 5.45605 0 0 0 + 12 444 2 0.20964 9.55621 5.66386 4.09964 0 0 0 + 13 444 3 0.03193 19.38728 8.01844 0.29841 0 0 0 + 14 444 4 -0.39965 18.30059 8.67235 0.94403 0 0 0 + 15 444 1 0.05269 20.09420 7.66052 1.04704 0 0 0 + 16 444 1 0.05269 19.01558 7.17130 -0.27928 0 0 0 + 17 444 1 0.05269 19.89453 8.71684 -0.36839 0 0 0 + 18 444 2 0.20964 17.72537 8.98355 0.21436 0 0 0 + 19 444 3 0.03193 3.43963 14.29741 12.62221 0 0 0 + 20 444 4 -0.39965 3.07671 15.61822 12.23631 0 0 0 + 21 444 1 0.05269 4.27302 14.34187 13.32349 0 0 0 + 22 444 1 0.05269 2.59308 13.81008 13.10508 0 0 0 + 23 444 1 0.05269 3.73991 13.72415 11.74356 0 0 0 + 24 444 2 0.20964 2.32966 15.52033 11.61130 0 0 0 + 25 444 3 0.03193 16.06751 17.84957 14.39706 0 0 0 + 26 444 4 -0.39965 15.98970 19.07282 15.11734 0 0 0 + 27 444 1 0.05269 16.77526 17.18402 14.89204 0 0 0 + 28 444 1 0.05269 15.08510 17.37867 14.36938 0 0 0 + 29 444 1 0.05269 16.40684 18.04085 13.37809 0 0 0 + 30 444 2 0.20964 15.35997 19.62900 14.61094 0 0 0 + 31 444 3 0.03193 5.61540 13.90261 0.28024 0 0 0 + 32 444 4 -0.39965 6.96329 14.33980 0.39819 0 0 0 + 33 444 1 0.05269 5.39381 13.18200 1.06831 0 0 0 + 34 444 1 0.05269 4.93854 14.75467 0.36989 0 0 0 + 35 444 1 0.05269 5.46825 13.42632 -0.68848 0 0 0 + 36 444 2 0.20964 7.08381 14.99923 -0.31851 0 0 0 + 37 444 3 0.03193 10.38444 13.74977 1.74423 0 0 0 + 38 444 4 -0.39965 10.34865 13.00890 2.96031 0 0 0 + 39 444 1 0.05269 11.31498 14.30998 1.68756 0 0 0 + 40 444 1 0.05269 10.32135 13.06875 0.89580 0 0 0 + 41 444 1 0.05269 9.54190 14.44190 1.71309 0 0 0 + 42 444 2 0.20964 9.45315 12.60486 2.98815 0 0 0 + 43 444 3 0.03193 2.71877 -0.19852 13.91482 0 0 0 + 44 444 4 -0.39965 2.55981 1.00656 13.16980 0 0 0 + 45 444 1 0.05269 3.42887 -0.85053 13.40421 0 0 0 + 46 444 1 0.05269 3.09835 0.02977 14.91227 0 0 0 + 47 444 1 0.05269 1.76062 -0.71177 13.99933 0 0 0 + 48 444 2 0.20964 1.92580 1.55260 13.68058 0 0 0 + 49 444 3 0.03193 12.86271 12.87291 9.10254 0 0 0 + 50 444 4 -0.39965 12.72964 12.19590 7.85730 0 0 0 + 51 444 1 0.05269 11.91715 12.83126 9.64447 0 0 0 + 52 444 1 0.05269 13.63913 12.39659 9.70188 0 0 0 + 53 444 1 0.05269 13.12955 13.91577 8.92585 0 0 0 + 54 444 2 0.20964 13.60640 12.28637 7.42000 0 0 0 + 55 444 3 0.03193 0.91345 1.84436 7.21758 0 0 0 + 56 444 4 -0.39965 0.16704 0.83109 7.88260 0 0 0 + 57 444 1 0.05269 1.73149 1.39473 6.65448 0 0 0 + 58 444 1 0.05269 0.25949 2.38287 6.53090 0 0 0 + 59 444 1 0.05269 1.31674 2.54212 7.95173 0 0 0 + 60 444 2 0.20964 0.79209 0.41480 8.51642 0 0 0 + 61 444 3 0.03193 3.28235 16.40235 6.34784 0 0 0 + 62 444 4 -0.39965 4.40446 15.86811 5.64397 0 0 0 + 63 444 1 0.05269 3.52775 16.47384 7.40940 0 0 0 + 64 444 1 0.05269 3.04852 17.39543 5.96551 0 0 0 + 65 444 1 0.05269 2.41989 15.75077 6.22278 0 0 0 + 66 444 2 0.20964 4.15040 15.88018 4.69552 0 0 0 + 67 444 3 0.03193 14.28685 11.84833 2.69644 0 0 0 + 68 444 4 -0.39965 14.47540 12.00775 4.09802 0 0 0 + 69 444 1 0.05269 15.22519 11.52503 2.24449 0 0 0 + 70 444 1 0.05269 13.51978 11.09713 2.50925 0 0 0 + 71 444 1 0.05269 13.98187 12.79680 2.25228 0 0 0 + 72 444 2 0.20964 13.60420 12.29868 4.44979 0 0 0 + 73 444 3 0.03193 3.74650 0.37490 9.28202 0 0 0 + 74 444 4 -0.39965 4.68624 1.26369 8.68537 0 0 0 + 75 444 1 0.05269 4.28178 -0.38700 9.84868 0 0 0 + 76 444 1 0.05269 3.08874 0.92642 9.95440 0 0 0 + 77 444 1 0.05269 3.15691 -0.10643 8.50276 0 0 0 + 78 444 2 0.20964 4.15269 1.92251 8.18619 0 0 0 + 79 444 3 0.03193 17.93191 1.98830 17.28592 0 0 0 + 80 444 4 -0.39965 16.68990 1.36769 17.60090 0 0 0 + 81 444 1 0.05269 18.23740 2.63433 18.10865 0 0 0 + 82 444 1 0.05269 18.69345 1.22519 17.12938 0 0 0 + 83 444 1 0.05269 17.82727 2.59026 16.38313 0 0 0 + 84 444 2 0.20964 16.45659 0.83462 16.81232 0 0 0 + 85 444 3 0.03193 4.61466 10.52979 17.10957 0 0 0 + 86 444 4 -0.39965 3.62035 11.42538 17.60198 0 0 0 + 87 444 1 0.05269 5.60177 10.98718 17.19552 0 0 0 + 88 444 1 0.05269 4.60514 9.60666 17.68872 0 0 0 + 89 444 1 0.05269 4.42040 10.30112 16.06086 0 0 0 + 90 444 2 0.20964 2.76200 10.96432 17.46823 0 0 0 + 91 444 3 0.03193 4.21479 2.76452 1.93621 0 0 0 + 92 444 4 -0.39965 3.45640 2.43822 3.09183 0 0 0 + 93 444 1 0.05269 5.15561 3.22498 2.23935 0 0 0 + 94 444 1 0.05269 4.42333 1.85922 1.36296 0 0 0 + 95 444 1 0.05269 3.65868 3.46500 1.31342 0 0 0 + 96 444 2 0.20964 2.68968 1.92747 2.75853 0 0 0 + 97 444 3 0.03193 2.10781 10.76856 1.36312 0 0 0 + 98 444 4 -0.39965 0.80698 11.27394 1.07892 0 0 0 + 99 444 1 0.05269 2.85114 11.53660 1.14272 0 0 0 + 100 444 1 0.05269 2.17873 10.49350 2.41651 0 0 0 + 101 444 1 0.05269 2.31220 9.89096 0.74802 0 0 0 + 102 444 2 0.20964 0.18009 10.55168 1.30975 0 0 0 + 103 444 3 0.03193 16.26093 8.92927 6.57643 0 0 0 + 104 444 4 -0.39965 15.77968 8.06983 7.60177 0 0 0 + 105 444 1 0.05269 17.30509 9.17300 6.76897 0 0 0 + 106 444 1 0.05269 16.18069 8.42876 5.61195 0 0 0 + 107 444 1 0.05269 15.67380 9.84869 6.55835 0 0 0 + 108 444 2 0.20964 14.84042 7.91008 7.37720 0 0 0 + 109 444 3 0.03193 17.80004 2.06792 1.87371 0 0 0 + 110 444 4 -0.39965 18.48862 0.99081 1.24012 0 0 0 + 111 444 1 0.05269 18.23871 2.25534 2.85453 0 0 0 + 112 444 1 0.05269 17.87937 2.96817 1.26859 0 0 0 + 113 444 1 0.05269 16.74643 1.80633 1.99693 0 0 0 + 114 444 2 0.20964 18.02202 0.85350 0.38356 0 0 0 + 115 444 3 0.03193 13.75521 14.57173 15.42181 0 0 0 + 116 444 4 -0.39965 12.73183 15.48504 15.80455 0 0 0 + 117 444 1 0.05269 14.51862 14.53760 16.20019 0 0 0 + 118 444 1 0.05269 13.33164 13.57618 15.29114 0 0 0 + 119 444 1 0.05269 14.21175 14.89091 14.48437 0 0 0 + 120 444 2 0.20964 12.11746 15.52768 15.03694 0 0 0 + 121 444 3 0.03193 6.22569 16.46321 11.49168 0 0 0 + 122 444 4 -0.39965 7.37834 15.65849 11.27192 0 0 0 + 123 444 1 0.05269 6.47325 17.50688 11.31115 0 0 0 + 124 444 1 0.05269 5.42639 16.16714 10.80967 0 0 0 + 125 444 1 0.05269 5.88670 16.35324 12.52283 0 0 0 + 126 444 2 0.20964 7.09224 14.73066 11.41776 0 0 0 + 127 444 3 0.03193 20.01012 9.33317 4.86657 0 0 0 + 128 444 4 -0.39965 19.63827 8.14994 5.56401 0 0 0 + 129 444 1 0.05269 20.82510 9.82112 5.40128 0 0 0 + 130 444 1 0.05269 20.34186 9.07963 3.85908 0 0 0 + 131 444 1 0.05269 19.16051 10.01349 4.80673 0 0 0 + 132 444 2 0.20964 18.86130 7.79949 5.07585 0 0 0 + 133 444 3 0.03193 5.99486 1.97634 5.72513 0 0 0 + 134 444 4 -0.39965 6.74021 3.13466 6.08586 0 0 0 + 135 444 1 0.05269 4.92875 2.19578 5.79288 0 0 0 + 136 444 1 0.05269 6.23376 1.68432 4.70221 0 0 0 + 137 444 1 0.05269 6.23815 1.15441 6.40034 0 0 0 + 138 444 2 0.20964 7.67684 2.83917 6.07790 0 0 0 + 139 444 3 0.03193 13.03835 7.12913 5.28770 0 0 0 + 140 444 4 -0.39965 13.02644 7.55487 6.64544 0 0 0 + 141 444 1 0.05269 12.06949 6.70203 5.02747 0 0 0 + 142 444 1 0.05269 13.24117 7.98172 4.63978 0 0 0 + 143 444 1 0.05269 13.81531 6.37647 5.14697 0 0 0 + 144 444 2 0.20964 12.38966 8.29858 6.65964 0 0 0 + 145 444 3 0.03193 10.64649 1.42163 6.99575 0 0 0 + 146 444 4 -0.39965 11.32932 1.55767 8.23581 0 0 0 + 147 444 1 0.05269 9.77461 0.78340 7.13967 0 0 0 + 148 444 1 0.05269 10.32031 2.40213 6.64261 0 0 0 + 149 444 1 0.05269 11.30461 0.96891 6.25436 0 0 0 + 150 444 2 0.20964 12.13048 2.09412 8.04749 0 0 0 + 151 444 3 0.03193 7.70974 10.56643 0.43745 0 0 0 + 152 444 4 -0.39965 6.69643 10.25499 1.38817 0 0 0 + 153 444 1 0.05269 8.59868 10.91732 0.96199 0 0 0 + 154 444 1 0.05269 7.96121 9.67471 -0.13665 0 0 0 + 155 444 1 0.05269 7.36428 11.34806 -0.24011 0 0 0 + 156 444 2 0.20964 5.94241 9.89154 0.87302 0 0 0 + 157 444 3 0.03193 12.78344 1.18067 14.16301 0 0 0 + 158 444 4 -0.39965 14.01647 1.62010 13.60417 0 0 0 + 159 444 1 0.05269 12.98217 0.47776 14.97222 0 0 0 + 160 444 1 0.05269 12.23227 2.03435 14.55662 0 0 0 + 161 444 1 0.05269 12.18352 0.68832 13.39874 0 0 0 + 162 444 2 0.20964 13.77530 2.26070 12.89474 0 0 0 + 163 444 3 0.03193 16.94139 17.42253 1.05686 0 0 0 + 164 444 4 -0.39965 16.08424 16.29569 1.04946 0 0 0 + 165 444 1 0.05269 17.18791 17.69368 0.02960 0 0 0 + 166 444 1 0.05269 16.43795 18.25970 1.54236 0 0 0 + 167 444 1 0.05269 17.85566 17.18021 1.60025 0 0 0 + 168 444 2 0.20964 15.85827 16.14412 1.99459 0 0 0 + 169 444 3 0.03193 12.48878 18.07306 2.58158 0 0 0 + 170 444 4 -0.39965 13.76343 18.70451 2.65479 0 0 0 + 171 444 1 0.05269 12.02971 18.30966 1.62310 0 0 0 + 172 444 1 0.05269 12.61189 16.99304 2.67149 0 0 0 + 173 444 1 0.05269 11.85062 18.43623 3.38623 0 0 0 + 174 444 2 0.20964 14.05960 18.54980 3.57438 0 0 0 + 175 444 3 0.03193 19.92937 14.32320 3.09954 0 0 0 + 176 444 4 -0.39965 20.47921 14.98239 4.23349 0 0 0 + 177 444 1 0.05269 19.06424 14.88021 2.74247 0 0 0 + 178 444 1 0.05269 20.67424 14.26863 2.30532 0 0 0 + 179 444 1 0.05269 19.62003 13.31457 3.37662 0 0 0 + 180 444 2 0.20964 21.24382 14.42340 4.50083 0 0 0 + 181 444 3 0.03193 10.63009 10.62036 5.48247 0 0 0 + 182 444 4 -0.39965 11.32080 9.96459 6.53930 0 0 0 + 183 444 1 0.05269 9.97896 9.90801 4.97371 0 0 0 + 184 444 1 0.05269 10.02580 11.43533 5.88411 0 0 0 + 185 444 1 0.05269 11.34799 11.02578 4.76860 0 0 0 + 186 444 2 0.20964 11.85790 10.67095 6.95281 0 0 0 + 187 444 3 0.03193 15.65699 9.09727 17.99408 0 0 0 + 188 444 4 -0.39965 16.90142 9.78939 17.98916 0 0 0 + 189 444 1 0.05269 15.04412 9.44428 18.82685 0 0 0 + 190 444 1 0.05269 15.12611 9.28242 17.05809 0 0 0 + 191 444 1 0.05269 15.82887 8.02576 18.10423 0 0 0 + 192 444 2 0.20964 17.40700 9.38003 17.24481 0 0 0 + 193 444 3 0.03193 17.18063 5.09511 5.97377 0 0 0 + 194 444 4 -0.39965 17.00699 3.69621 6.16625 0 0 0 + 195 444 1 0.05269 16.80087 5.38050 4.99222 0 0 0 + 196 444 1 0.05269 16.63290 5.63866 6.74297 0 0 0 + 197 444 1 0.05269 18.23947 5.34654 6.03632 0 0 0 + 198 444 2 0.20964 17.37922 3.51369 7.05728 0 0 0 + 199 444 3 0.03193 9.27176 16.96360 18.60348 0 0 0 + 200 444 4 -0.39965 10.16048 17.88001 19.23027 0 0 0 + 201 444 1 0.05269 8.24372 17.25233 18.82182 0 0 0 + 202 444 1 0.05269 9.42846 16.97594 17.52377 0 0 0 + 203 444 1 0.05269 9.45162 15.95835 18.98512 0 0 0 + 204 444 2 0.20964 11.05433 17.57777 18.98374 0 0 0 + 205 444 3 0.03193 19.02698 11.32629 8.74382 0 0 0 + 206 444 4 -0.39965 19.55395 11.57496 7.44476 0 0 0 + 207 444 1 0.05269 19.84306 11.28874 9.46486 0 0 0 + 208 444 1 0.05269 18.34041 12.12651 9.02172 0 0 0 + 209 444 1 0.05269 18.49941 10.37268 8.75573 0 0 0 + 210 444 2 0.20964 18.77484 11.55877 6.84653 0 0 0 + 211 444 3 0.03193 13.70984 17.91381 18.18096 0 0 0 + 212 444 4 -0.39965 12.78082 16.86629 18.42949 0 0 0 + 213 444 1 0.05269 14.65264 17.49419 17.82801 0 0 0 + 214 444 1 0.05269 13.30579 18.58561 17.42320 0 0 0 + 215 444 1 0.05269 13.88737 18.47185 19.10049 0 0 0 + 216 444 2 0.20964 12.70938 16.39241 17.57615 0 0 0 + 217 444 3 0.03193 7.96084 1.88854 9.90132 0 0 0 + 218 444 4 -0.39965 7.16836 0.76877 10.27166 0 0 0 + 219 444 1 0.05269 8.08701 1.90679 8.82000 0 0 0 + 220 444 1 0.05269 7.47244 2.80930 10.22050 0 0 0 + 221 444 1 0.05269 8.93667 1.81039 10.37952 0 0 0 + 222 444 2 0.20964 6.33219 0.87991 9.77220 0 0 0 + 223 444 3 0.03193 8.67989 16.70958 5.83790 0 0 0 + 224 444 4 -0.39965 8.12024 17.60224 6.79460 0 0 0 + 225 444 1 0.05269 8.09228 16.75013 4.91967 0 0 0 + 226 444 1 0.05269 9.70728 17.00048 5.62151 0 0 0 + 227 444 1 0.05269 8.66415 15.69153 6.22812 0 0 0 + 228 444 2 0.20964 8.61953 17.44038 7.62546 0 0 0 + 229 444 3 0.03193 8.92912 4.00904 0.50900 0 0 0 + 230 444 4 -0.39965 8.96759 5.27857 -0.13058 0 0 0 + 231 444 1 0.05269 8.33969 4.08141 1.42278 0 0 0 + 232 444 1 0.05269 8.47682 3.27429 -0.15833 0 0 0 + 233 444 1 0.05269 9.94193 3.69036 0.75961 0 0 0 + 234 444 2 0.20964 9.53405 5.14064 -0.92363 0 0 0 + 235 444 3 0.03193 14.12006 6.78048 11.59632 0 0 0 + 236 444 4 -0.39965 13.07688 7.13628 10.69542 0 0 0 + 237 444 1 0.05269 14.86068 7.57932 11.63302 0 0 0 + 238 444 1 0.05269 13.70582 6.62813 12.59405 0 0 0 + 239 444 1 0.05269 14.60290 5.86276 11.26001 0 0 0 + 240 444 2 0.20964 12.46641 6.36815 10.68540 0 0 0 + 241 444 3 0.03193 11.17366 12.60541 17.35410 0 0 0 + 242 444 4 -0.39965 11.02139 13.96786 17.73395 0 0 0 + 243 444 1 0.05269 10.47704 11.99021 17.92352 0 0 0 + 244 444 1 0.05269 10.96097 12.49402 16.29011 0 0 0 + 245 444 1 0.05269 12.19388 12.27752 17.55780 0 0 0 + 246 444 2 0.20964 11.62997 14.46572 17.15437 0 0 0 + 247 444 3 0.03193 13.59375 17.68257 6.60725 0 0 0 + 248 444 4 -0.39965 14.41796 18.19915 5.56896 0 0 0 + 249 444 1 0.05269 12.56750 17.59958 6.25257 0 0 0 + 250 444 1 0.05269 13.95140 16.69610 6.90350 0 0 0 + 251 444 1 0.05269 13.62441 18.35441 7.46523 0 0 0 + 252 444 2 0.20964 15.31701 18.26489 5.96089 0 0 0 + 253 444 3 0.03193 5.00550 8.70879 7.93082 0 0 0 + 254 444 4 -0.39965 5.30633 7.53730 7.17920 0 0 0 + 255 444 1 0.05269 3.92410 8.80228 8.03546 0 0 0 + 256 444 1 0.05269 5.45973 8.64206 8.92134 0 0 0 + 257 444 1 0.05269 5.39337 9.58812 7.41497 0 0 0 + 258 444 2 0.20964 6.28240 7.52607 7.08649 0 0 0 + 259 444 3 0.03193 19.22046 1.28969 13.91270 0 0 0 + 260 444 4 -0.39965 20.08805 2.12898 14.66921 0 0 0 + 261 444 1 0.05269 18.36269 1.87059 13.57299 0 0 0 + 262 444 1 0.05269 19.74873 0.89208 13.04541 0 0 0 + 263 444 1 0.05269 18.87095 0.46148 14.53042 0 0 0 + 264 444 2 0.20964 20.73583 1.52580 15.09558 0 0 0 + 265 444 3 0.03193 5.65052 5.42047 10.40141 0 0 0 + 266 444 4 -0.39965 6.43233 5.15576 11.55959 0 0 0 + 267 444 1 0.05269 4.77591 4.76790 10.40245 0 0 0 + 268 444 1 0.05269 5.31750 6.45945 10.40208 0 0 0 + 269 444 1 0.05269 6.23775 5.22771 9.50311 0 0 0 + 270 444 2 0.20964 7.22334 5.73649 11.49818 0 0 0 + 271 444 3 0.03193 13.28289 5.81639 20.26495 0 0 0 + 272 444 4 -0.39965 14.46108 5.91020 19.47306 0 0 0 + 273 444 1 0.05269 12.54449 6.53149 19.89956 0 0 0 + 274 444 1 0.05269 12.86565 4.81041 20.20085 0 0 0 + 275 444 1 0.05269 13.51599 6.04282 21.30628 0 0 0 + 276 444 2 0.20964 15.06689 5.21681 19.82048 0 0 0 + 277 444 3 0.03193 8.93119 18.18764 13.28407 0 0 0 + 278 444 4 -0.39965 7.83369 17.94987 14.15258 0 0 0 + 279 444 1 0.05269 8.62256 18.85058 12.47662 0 0 0 + 280 444 1 0.05269 9.74951 18.65521 13.83984 0 0 0 + 281 444 1 0.05269 9.27914 17.24313 12.85839 0 0 0 + 282 444 2 0.20964 8.18034 17.33710 14.83873 0 0 0 + 283 444 3 0.03193 5.79456 2.19968 17.80701 0 0 0 + 284 444 4 -0.39965 6.24133 2.96696 16.69489 0 0 0 + 285 444 1 0.05269 5.95925 2.76662 18.72146 0 0 0 + 286 444 1 0.05269 4.73133 1.97951 17.70368 0 0 0 + 287 444 1 0.05269 6.35360 1.26369 17.85787 0 0 0 + 288 444 2 0.20964 6.11167 2.36984 15.93032 0 0 0 + 289 444 3 0.03193 7.02257 8.31146 13.32419 0 0 0 + 290 444 4 -0.39965 6.81830 9.58617 13.92250 0 0 0 + 291 444 1 0.05269 6.70351 7.53159 14.01772 0 0 0 + 292 444 1 0.05269 6.43819 8.23664 12.40602 0 0 0 + 293 444 1 0.05269 8.08019 8.17829 13.09255 0 0 0 + 294 444 2 0.20964 7.15181 10.23194 13.26245 0 0 0 + 295 444 3 0.03193 14.02631 3.46938 16.96774 0 0 0 + 296 444 4 -0.39965 13.54366 2.24600 17.51611 0 0 0 + 297 444 1 0.05269 13.77498 3.53066 15.91013 0 0 0 + 298 444 1 0.05269 13.56595 4.30739 17.48900 0 0 0 + 299 444 1 0.05269 15.10861 3.52592 17.07904 0 0 0 + 300 444 2 0.20964 13.94305 2.20406 18.41525 0 0 0 + 301 444 3 0.03193 1.20831 18.57486 2.95108 0 0 0 + 302 444 4 -0.39965 1.22576 19.81993 2.26075 0 0 0 + 303 444 1 0.05269 0.55458 18.64320 3.82147 0 0 0 + 304 444 1 0.05269 0.84728 17.78646 2.28798 0 0 0 + 305 444 1 0.05269 2.21813 18.32995 3.28130 0 0 0 + 306 444 2 0.20964 0.30364 19.97372 1.97883 0 0 0 + 307 444 3 0.03193 13.27354 18.56828 10.67719 0 0 0 + 308 444 4 -0.39965 12.48821 17.54334 10.07841 0 0 0 + 309 444 1 0.05269 12.67535 19.47728 10.75867 0 0 0 + 310 444 1 0.05269 13.59103 18.25289 11.67155 0 0 0 + 311 444 1 0.05269 14.15208 18.77184 10.06448 0 0 0 + 312 444 2 0.20964 13.09935 16.78781 9.93641 0 0 0 + 313 444 3 0.03193 6.36730 14.29234 8.10345 0 0 0 + 314 444 4 -0.39965 6.40678 13.98673 6.71535 0 0 0 + 315 444 1 0.05269 5.36805 14.09806 8.49177 0 0 0 + 316 444 1 0.05269 7.08832 13.66856 8.63166 0 0 0 + 317 444 1 0.05269 6.61905 15.34196 8.25886 0 0 0 + 318 444 2 0.20964 5.76587 14.60457 6.30951 0 0 0 + 319 444 3 0.03193 2.65328 9.08063 11.58358 0 0 0 + 320 444 4 -0.39965 2.00217 9.04988 10.31818 0 0 0 + 321 444 1 0.05269 2.77179 8.06201 11.95511 0 0 0 + 322 444 1 0.05269 3.63556 9.54427 11.48302 0 0 0 + 323 444 1 0.05269 2.05382 9.65342 12.29226 0 0 0 + 324 444 2 0.20964 1.90245 9.98881 10.05330 0 0 0 + 325 444 3 0.03193 16.09537 13.47946 18.75299 0 0 0 + 326 444 4 -0.39965 15.35647 12.29789 19.02596 0 0 0 + 327 444 1 0.05269 15.44738 14.34606 18.88103 0 0 0 + 328 444 1 0.05269 16.93959 13.54850 19.44072 0 0 0 + 329 444 1 0.05269 16.46394 13.45617 17.72675 0 0 0 + 330 444 2 0.20964 15.94172 11.56097 18.74998 0 0 0 + 331 444 3 0.03193 5.36713 6.40841 19.02468 0 0 0 + 332 444 4 -0.39965 6.23337 6.92207 18.01801 0 0 0 + 333 444 1 0.05269 4.33549 6.65297 18.77623 0 0 0 + 334 444 1 0.05269 5.47707 5.32425 19.08654 0 0 0 + 335 444 1 0.05269 5.62819 6.85675 19.98559 0 0 0 + 336 444 2 0.20964 7.13950 6.67949 18.31120 0 0 0 + 337 444 3 0.03193 1.77513 13.81811 9.21198 0 0 0 + 338 444 4 -0.39965 0.83100 14.28966 10.16552 0 0 0 + 339 444 1 0.05269 1.29728 13.75593 8.23483 0 0 0 + 340 444 1 0.05269 2.62178 14.50388 9.15673 0 0 0 + 341 444 1 0.05269 2.12880 12.82836 9.50371 0 0 0 + 342 444 2 0.20964 1.30194 14.30478 11.02173 0 0 0 + 343 444 3 0.03193 21.59943 4.06368 17.75073 0 0 0 + 344 444 4 -0.39965 21.85233 3.04768 18.71336 0 0 0 + 345 444 1 0.05269 22.11092 3.81498 16.82008 0 0 0 + 346 444 1 0.05269 20.52800 4.13659 17.56408 0 0 0 + 347 444 1 0.05269 21.97071 5.01986 18.11886 0 0 0 + 348 444 2 0.20964 21.40074 3.34325 19.53474 0 0 0 + 349 444 3 0.03193 16.52622 4.73908 13.63762 0 0 0 + 350 444 4 -0.39965 15.55282 5.45454 14.38889 0 0 0 + 351 444 1 0.05269 16.03370 3.96708 13.04616 0 0 0 + 352 444 1 0.05269 17.05262 5.42291 12.96909 0 0 0 + 353 444 1 0.05269 17.24076 4.27126 14.31456 0 0 0 + 354 444 2 0.20964 16.06701 6.07053 14.95693 0 0 0 + 355 444 3 0.03193 20.20141 14.20302 18.50889 0 0 0 + 356 444 4 -0.39965 21.44729 13.78288 19.04009 0 0 0 + 357 444 1 0.05269 20.32931 15.13613 17.95996 0 0 0 + 358 444 1 0.05269 19.81275 13.43791 17.83324 0 0 0 + 359 444 1 0.05269 19.48848 14.36395 19.32079 0 0 0 + 360 444 2 0.20964 21.25026 12.96615 19.54627 0 0 0 + 361 444 3 0.03193 3.32298 14.94425 16.50422 0 0 0 + 362 444 4 -0.39965 4.38694 14.00670 16.37303 0 0 0 + 363 444 1 0.05269 3.54498 15.83135 15.91086 0 0 0 + 364 444 1 0.05269 2.39143 14.50263 16.15017 0 0 0 + 365 444 1 0.05269 3.21366 15.23418 17.54978 0 0 0 + 366 444 2 0.20964 4.09659 13.20452 16.85511 0 0 0 + 367 444 3 0.03193 10.00891 1.19780 16.80998 0 0 0 + 368 444 4 -0.39965 10.58951 1.67540 18.01757 0 0 0 + 369 444 1 0.05269 8.95573 0.97837 16.97853 0 0 0 + 370 444 1 0.05269 10.09279 1.95889 16.03422 0 0 0 + 371 444 1 0.05269 10.51430 0.28729 16.48583 0 0 0 + 372 444 2 0.20964 11.54632 1.78202 17.83462 0 0 0 + 373 444 3 0.03193 1.31776 5.21190 2.64974 0 0 0 + 374 444 4 -0.39965 0.78156 4.20400 1.79964 0 0 0 + 375 444 1 0.05269 2.00060 5.84322 2.08036 0 0 0 + 376 444 1 0.05269 0.50993 5.82499 3.05018 0 0 0 + 377 444 1 0.05269 1.85905 4.74873 3.47448 0 0 0 + 378 444 2 0.20964 0.20631 3.65922 2.38482 0 0 0 + 379 444 3 0.03193 5.74906 1.64126 13.27894 0 0 0 + 380 444 4 -0.39965 5.74933 0.96366 14.53304 0 0 0 + 381 444 1 0.05269 5.05775 2.48272 13.31880 0 0 0 + 382 444 1 0.05269 6.74849 2.01315 13.05234 0 0 0 + 383 444 1 0.05269 5.43187 0.95557 12.49248 0 0 0 + 384 444 2 0.20964 6.42516 0.25912 14.43537 0 0 0 + + +Bonds + + 1 1 1 2 + 2 3 1 3 + 3 3 1 4 + 4 3 1 5 + 5 2 2 6 + 6 1 7 8 + 7 3 7 9 + 8 3 7 10 + 9 3 7 11 + 10 2 8 12 + 11 1 13 14 + 12 3 13 15 + 13 3 13 16 + 14 3 13 17 + 15 2 14 18 + 16 1 19 20 + 17 3 19 21 + 18 3 19 22 + 19 3 19 23 + 20 2 20 24 + 21 1 25 26 + 22 3 25 27 + 23 3 25 28 + 24 3 25 29 + 25 2 26 30 + 26 1 31 32 + 27 3 31 33 + 28 3 31 34 + 29 3 31 35 + 30 2 32 36 + 31 1 37 38 + 32 3 37 39 + 33 3 37 40 + 34 3 37 41 + 35 2 38 42 + 36 1 43 44 + 37 3 43 45 + 38 3 43 46 + 39 3 43 47 + 40 2 44 48 + 41 1 49 50 + 42 3 49 51 + 43 3 49 52 + 44 3 49 53 + 45 2 50 54 + 46 1 55 56 + 47 3 55 57 + 48 3 55 58 + 49 3 55 59 + 50 2 56 60 + 51 1 61 62 + 52 3 61 63 + 53 3 61 64 + 54 3 61 65 + 55 2 62 66 + 56 1 67 68 + 57 3 67 69 + 58 3 67 70 + 59 3 67 71 + 60 2 68 72 + 61 1 73 74 + 62 3 73 75 + 63 3 73 76 + 64 3 73 77 + 65 2 74 78 + 66 1 79 80 + 67 3 79 81 + 68 3 79 82 + 69 3 79 83 + 70 2 80 84 + 71 1 85 86 + 72 3 85 87 + 73 3 85 88 + 74 3 85 89 + 75 2 86 90 + 76 1 91 92 + 77 3 91 93 + 78 3 91 94 + 79 3 91 95 + 80 2 92 96 + 81 1 97 98 + 82 3 97 99 + 83 3 97 100 + 84 3 97 101 + 85 2 98 102 + 86 1 103 104 + 87 3 103 105 + 88 3 103 106 + 89 3 103 107 + 90 2 104 108 + 91 1 109 110 + 92 3 109 111 + 93 3 109 112 + 94 3 109 113 + 95 2 110 114 + 96 1 115 116 + 97 3 115 117 + 98 3 115 118 + 99 3 115 119 + 100 2 116 120 + 101 1 121 122 + 102 3 121 123 + 103 3 121 124 + 104 3 121 125 + 105 2 122 126 + 106 1 127 128 + 107 3 127 129 + 108 3 127 130 + 109 3 127 131 + 110 2 128 132 + 111 1 133 134 + 112 3 133 135 + 113 3 133 136 + 114 3 133 137 + 115 2 134 138 + 116 1 139 140 + 117 3 139 141 + 118 3 139 142 + 119 3 139 143 + 120 2 140 144 + 121 1 145 146 + 122 3 145 147 + 123 3 145 148 + 124 3 145 149 + 125 2 146 150 + 126 1 151 152 + 127 3 151 153 + 128 3 151 154 + 129 3 151 155 + 130 2 152 156 + 131 1 157 158 + 132 3 157 159 + 133 3 157 160 + 134 3 157 161 + 135 2 158 162 + 136 1 163 164 + 137 3 163 165 + 138 3 163 166 + 139 3 163 167 + 140 2 164 168 + 141 1 169 170 + 142 3 169 171 + 143 3 169 172 + 144 3 169 173 + 145 2 170 174 + 146 1 175 176 + 147 3 175 177 + 148 3 175 178 + 149 3 175 179 + 150 2 176 180 + 151 1 181 182 + 152 3 181 183 + 153 3 181 184 + 154 3 181 185 + 155 2 182 186 + 156 1 187 188 + 157 3 187 189 + 158 3 187 190 + 159 3 187 191 + 160 2 188 192 + 161 1 193 194 + 162 3 193 195 + 163 3 193 196 + 164 3 193 197 + 165 2 194 198 + 166 1 199 200 + 167 3 199 201 + 168 3 199 202 + 169 3 199 203 + 170 2 200 204 + 171 1 205 206 + 172 3 205 207 + 173 3 205 208 + 174 3 205 209 + 175 2 206 210 + 176 1 211 212 + 177 3 211 213 + 178 3 211 214 + 179 3 211 215 + 180 2 212 216 + 181 1 217 218 + 182 3 217 219 + 183 3 217 220 + 184 3 217 221 + 185 2 218 222 + 186 1 223 224 + 187 3 223 225 + 188 3 223 226 + 189 3 223 227 + 190 2 224 228 + 191 1 229 230 + 192 3 229 231 + 193 3 229 232 + 194 3 229 233 + 195 2 230 234 + 196 1 235 236 + 197 3 235 237 + 198 3 235 238 + 199 3 235 239 + 200 2 236 240 + 201 1 241 242 + 202 3 241 243 + 203 3 241 244 + 204 3 241 245 + 205 2 242 246 + 206 1 247 248 + 207 3 247 249 + 208 3 247 250 + 209 3 247 251 + 210 2 248 252 + 211 1 253 254 + 212 3 253 255 + 213 3 253 256 + 214 3 253 257 + 215 2 254 258 + 216 1 259 260 + 217 3 259 261 + 218 3 259 262 + 219 3 259 263 + 220 2 260 264 + 221 1 265 266 + 222 3 265 267 + 223 3 265 268 + 224 3 265 269 + 225 2 266 270 + 226 1 271 272 + 227 3 271 273 + 228 3 271 274 + 229 3 271 275 + 230 2 272 276 + 231 1 277 278 + 232 3 277 279 + 233 3 277 280 + 234 3 277 281 + 235 2 278 282 + 236 1 283 284 + 237 3 283 285 + 238 3 283 286 + 239 3 283 287 + 240 2 284 288 + 241 1 289 290 + 242 3 289 291 + 243 3 289 292 + 244 3 289 293 + 245 2 290 294 + 246 1 295 296 + 247 3 295 297 + 248 3 295 298 + 249 3 295 299 + 250 2 296 300 + 251 1 301 302 + 252 3 301 303 + 253 3 301 304 + 254 3 301 305 + 255 2 302 306 + 256 1 307 308 + 257 3 307 309 + 258 3 307 310 + 259 3 307 311 + 260 2 308 312 + 261 1 313 314 + 262 3 313 315 + 263 3 313 316 + 264 3 313 317 + 265 2 314 318 + 266 1 319 320 + 267 3 319 321 + 268 3 319 322 + 269 3 319 323 + 270 2 320 324 + 271 1 325 326 + 272 3 325 327 + 273 3 325 328 + 274 3 325 329 + 275 2 326 330 + 276 1 331 332 + 277 3 331 333 + 278 3 331 334 + 279 3 331 335 + 280 2 332 336 + 281 1 337 338 + 282 3 337 339 + 283 3 337 340 + 284 3 337 341 + 285 2 338 342 + 286 1 343 344 + 287 3 343 345 + 288 3 343 346 + 289 3 343 347 + 290 2 344 348 + 291 1 349 350 + 292 3 349 351 + 293 3 349 352 + 294 3 349 353 + 295 2 350 354 + 296 1 355 356 + 297 3 355 357 + 298 3 355 358 + 299 3 355 359 + 300 2 356 360 + 301 1 361 362 + 302 3 361 363 + 303 3 361 364 + 304 3 361 365 + 305 2 362 366 + 306 1 367 368 + 307 3 367 369 + 308 3 367 370 + 309 3 367 371 + 310 2 368 372 + 311 1 373 374 + 312 3 373 375 + 313 3 373 376 + 314 3 373 377 + 315 2 374 378 + 316 1 379 380 + 317 3 379 381 + 318 3 379 382 + 319 3 379 383 + 320 2 380 384 + +Angles + + 1 2 3 1 2 + 2 2 4 1 2 + 3 2 4 1 3 + 4 2 5 1 2 + 5 2 5 1 3 + 6 2 5 1 4 + 7 1 6 2 1 + 8 1 7 8 12 + 9 2 8 7 10 + 10 2 8 7 11 + 11 2 9 7 8 + 12 2 9 7 10 + 13 2 9 7 11 + 14 2 11 7 10 + 15 2 15 13 14 + 16 2 16 13 14 + 17 2 16 13 15 + 18 2 17 13 14 + 19 2 17 13 15 + 20 2 17 13 16 + 21 1 18 14 13 + 22 2 21 19 20 + 23 2 22 19 20 + 24 2 22 19 21 + 25 2 23 19 20 + 26 2 23 19 21 + 27 2 23 19 22 + 28 1 24 20 19 + 29 2 27 25 26 + 30 2 28 25 26 + 31 2 28 25 27 + 32 2 29 25 26 + 33 2 29 25 27 + 34 2 29 25 28 + 35 1 30 26 25 + 36 2 33 31 32 + 37 2 34 31 32 + 38 2 34 31 33 + 39 2 35 31 32 + 40 2 35 31 33 + 41 2 35 31 34 + 42 1 36 32 31 + 43 2 39 37 38 + 44 2 40 37 38 + 45 2 40 37 39 + 46 2 41 37 38 + 47 2 41 37 39 + 48 2 41 37 40 + 49 1 42 38 37 + 50 2 45 43 44 + 51 2 46 43 44 + 52 2 46 43 45 + 53 2 47 43 44 + 54 2 47 43 45 + 55 2 47 43 46 + 56 1 48 44 43 + 57 2 51 49 50 + 58 2 52 49 50 + 59 2 52 49 51 + 60 2 53 49 50 + 61 2 53 49 51 + 62 2 53 49 52 + 63 1 54 50 49 + 64 2 57 55 56 + 65 2 58 55 56 + 66 2 58 55 57 + 67 2 59 55 56 + 68 2 59 55 57 + 69 2 59 55 58 + 70 1 60 56 55 + 71 2 63 61 62 + 72 2 64 61 62 + 73 2 64 61 63 + 74 2 65 61 62 + 75 2 65 61 63 + 76 2 65 61 64 + 77 1 66 62 61 + 78 2 69 67 68 + 79 2 70 67 68 + 80 2 70 67 69 + 81 2 71 67 68 + 82 2 71 67 69 + 83 2 71 67 70 + 84 1 72 68 67 + 85 2 75 73 74 + 86 2 76 73 74 + 87 2 76 73 75 + 88 2 77 73 74 + 89 2 77 73 75 + 90 2 77 73 76 + 91 1 78 74 73 + 92 2 81 79 80 + 93 2 82 79 80 + 94 2 82 79 81 + 95 2 83 79 80 + 96 2 83 79 81 + 97 2 83 79 82 + 98 1 84 80 79 + 99 2 87 85 86 + 100 2 88 85 86 + 101 2 88 85 87 + 102 2 89 85 86 + 103 2 89 85 87 + 104 2 89 85 88 + 105 1 90 86 85 + 106 2 93 91 92 + 107 2 94 91 92 + 108 2 94 91 93 + 109 2 95 91 92 + 110 2 95 91 93 + 111 2 95 91 94 + 112 1 96 92 91 + 113 1 97 98 102 + 114 2 98 97 100 + 115 2 98 97 101 + 116 2 99 97 98 + 117 2 99 97 100 + 118 2 99 97 101 + 119 2 101 97 100 + 120 2 105 103 104 + 121 2 106 103 104 + 122 2 106 103 105 + 123 2 107 103 104 + 124 2 107 103 105 + 125 2 107 103 106 + 126 1 108 104 103 + 127 2 111 109 110 + 128 2 112 109 110 + 129 2 112 109 111 + 130 2 113 109 110 + 131 2 113 109 111 + 132 2 113 109 112 + 133 1 114 110 109 + 134 2 117 115 116 + 135 2 118 115 116 + 136 2 118 115 117 + 137 2 119 115 116 + 138 2 119 115 117 + 139 2 119 115 118 + 140 1 120 116 115 + 141 2 123 121 122 + 142 2 124 121 122 + 143 2 124 121 123 + 144 2 125 121 122 + 145 2 125 121 123 + 146 2 125 121 124 + 147 1 126 122 121 + 148 2 129 127 128 + 149 2 130 127 128 + 150 2 130 127 129 + 151 2 131 127 128 + 152 2 131 127 129 + 153 2 131 127 130 + 154 1 132 128 127 + 155 2 135 133 134 + 156 2 136 133 134 + 157 2 136 133 135 + 158 2 137 133 134 + 159 2 137 133 135 + 160 2 137 133 136 + 161 1 138 134 133 + 162 2 141 139 140 + 163 2 142 139 140 + 164 2 142 139 141 + 165 2 143 139 140 + 166 2 143 139 141 + 167 2 143 139 142 + 168 1 144 140 139 + 169 2 147 145 146 + 170 2 148 145 146 + 171 2 148 145 147 + 172 2 149 145 146 + 173 2 149 145 147 + 174 2 149 145 148 + 175 1 150 146 145 + 176 2 153 151 152 + 177 2 154 151 152 + 178 2 154 151 153 + 179 2 155 151 152 + 180 2 155 151 153 + 181 2 155 151 154 + 182 1 156 152 151 + 183 2 159 157 158 + 184 2 160 157 158 + 185 2 160 157 159 + 186 2 161 157 158 + 187 2 161 157 159 + 188 2 161 157 160 + 189 1 162 158 157 + 190 2 165 163 164 + 191 2 166 163 164 + 192 2 166 163 165 + 193 2 167 163 164 + 194 2 167 163 165 + 195 2 167 163 166 + 196 1 168 164 163 + 197 2 171 169 170 + 198 2 172 169 170 + 199 2 172 169 171 + 200 2 173 169 170 + 201 2 173 169 171 + 202 2 173 169 172 + 203 1 174 170 169 + 204 2 177 175 176 + 205 2 178 175 176 + 206 2 178 175 177 + 207 2 179 175 176 + 208 2 179 175 177 + 209 2 179 175 178 + 210 1 180 176 175 + 211 2 183 181 182 + 212 2 184 181 182 + 213 2 184 181 183 + 214 2 185 181 182 + 215 2 185 181 183 + 216 2 185 181 184 + 217 1 186 182 181 + 218 2 189 187 188 + 219 2 190 187 188 + 220 2 190 187 189 + 221 2 191 187 188 + 222 2 191 187 189 + 223 2 191 187 190 + 224 1 192 188 187 + 225 2 195 193 194 + 226 2 196 193 194 + 227 2 196 193 195 + 228 2 197 193 194 + 229 2 197 193 195 + 230 2 197 193 196 + 231 1 198 194 193 + 232 2 201 199 200 + 233 2 202 199 200 + 234 2 202 199 201 + 235 2 203 199 200 + 236 2 203 199 201 + 237 2 203 199 202 + 238 1 204 200 199 + 239 2 207 205 206 + 240 2 208 205 206 + 241 2 208 205 207 + 242 2 209 205 206 + 243 2 209 205 207 + 244 2 209 205 208 + 245 1 210 206 205 + 246 2 213 211 212 + 247 2 214 211 212 + 248 2 214 211 213 + 249 2 215 211 212 + 250 2 215 211 213 + 251 2 215 211 214 + 252 1 216 212 211 + 253 2 219 217 218 + 254 2 220 217 218 + 255 2 220 217 219 + 256 2 221 217 218 + 257 2 221 217 219 + 258 2 221 217 220 + 259 1 222 218 217 + 260 2 225 223 224 + 261 2 226 223 224 + 262 2 226 223 225 + 263 2 227 223 224 + 264 2 227 223 225 + 265 2 227 223 226 + 266 1 228 224 223 + 267 2 231 229 230 + 268 2 232 229 230 + 269 2 232 229 231 + 270 2 233 229 230 + 271 2 233 229 231 + 272 2 233 229 232 + 273 1 234 230 229 + 274 2 237 235 236 + 275 2 238 235 236 + 276 2 238 235 237 + 277 2 239 235 236 + 278 2 239 235 237 + 279 2 239 235 238 + 280 1 240 236 235 + 281 2 243 241 242 + 282 2 244 241 242 + 283 2 244 241 243 + 284 2 245 241 242 + 285 2 245 241 243 + 286 2 245 241 244 + 287 1 246 242 241 + 288 2 249 247 248 + 289 2 250 247 248 + 290 2 250 247 249 + 291 2 251 247 248 + 292 2 251 247 249 + 293 2 251 247 250 + 294 1 252 248 247 + 295 2 255 253 254 + 296 2 256 253 254 + 297 2 256 253 255 + 298 2 257 253 254 + 299 2 257 253 255 + 300 2 257 253 256 + 301 1 258 254 253 + 302 2 261 259 260 + 303 2 262 259 260 + 304 2 262 259 261 + 305 2 263 259 260 + 306 2 263 259 261 + 307 2 263 259 262 + 308 1 264 260 259 + 309 2 267 265 266 + 310 2 268 265 266 + 311 2 268 265 267 + 312 2 269 265 266 + 313 2 269 265 267 + 314 2 269 265 268 + 315 1 270 266 265 + 316 2 273 271 272 + 317 2 274 271 272 + 318 2 274 271 273 + 319 2 275 271 272 + 320 2 275 271 273 + 321 2 275 271 274 + 322 1 276 272 271 + 323 2 279 277 278 + 324 2 280 277 278 + 325 2 280 277 279 + 326 2 281 277 278 + 327 2 281 277 279 + 328 2 281 277 280 + 329 1 282 278 277 + 330 2 285 283 284 + 331 2 286 283 284 + 332 2 286 283 285 + 333 2 287 283 284 + 334 2 287 283 285 + 335 2 287 283 286 + 336 1 288 284 283 + 337 2 291 289 290 + 338 2 292 289 290 + 339 2 292 289 291 + 340 2 293 289 290 + 341 2 293 289 291 + 342 2 293 289 292 + 343 1 294 290 289 + 344 2 297 295 296 + 345 2 298 295 296 + 346 2 298 295 297 + 347 2 299 295 296 + 348 2 299 295 297 + 349 2 299 295 298 + 350 1 300 296 295 + 351 2 303 301 302 + 352 2 304 301 302 + 353 2 304 301 303 + 354 2 305 301 302 + 355 2 305 301 303 + 356 2 305 301 304 + 357 1 306 302 301 + 358 2 309 307 308 + 359 2 310 307 308 + 360 2 310 307 309 + 361 2 311 307 308 + 362 2 311 307 309 + 363 2 311 307 310 + 364 1 312 308 307 + 365 2 315 313 314 + 366 2 316 313 314 + 367 2 316 313 315 + 368 2 317 313 314 + 369 2 317 313 315 + 370 2 317 313 316 + 371 1 318 314 313 + 372 2 321 319 320 + 373 2 322 319 320 + 374 2 322 319 321 + 375 2 323 319 320 + 376 2 323 319 321 + 377 2 323 319 322 + 378 1 324 320 319 + 379 2 327 325 326 + 380 2 328 325 326 + 381 2 328 325 327 + 382 2 329 325 326 + 383 2 329 325 327 + 384 2 329 325 328 + 385 1 330 326 325 + 386 2 333 331 332 + 387 2 334 331 332 + 388 2 334 331 333 + 389 2 335 331 332 + 390 2 335 331 333 + 391 2 335 331 334 + 392 1 336 332 331 + 393 2 339 337 338 + 394 2 340 337 338 + 395 2 340 337 339 + 396 2 341 337 338 + 397 2 341 337 339 + 398 2 341 337 340 + 399 1 342 338 337 + 400 2 345 343 344 + 401 2 346 343 344 + 402 2 346 343 345 + 403 2 347 343 344 + 404 2 347 343 345 + 405 2 347 343 346 + 406 1 348 344 343 + 407 2 351 349 350 + 408 2 352 349 350 + 409 2 352 349 351 + 410 2 353 349 350 + 411 2 353 349 351 + 412 2 353 349 352 + 413 1 354 350 349 + 414 2 357 355 356 + 415 2 358 355 356 + 416 2 358 355 357 + 417 2 359 355 356 + 418 2 359 355 357 + 419 2 359 355 358 + 420 1 360 356 355 + 421 2 363 361 362 + 422 2 364 361 362 + 423 2 364 361 363 + 424 2 365 361 362 + 425 2 365 361 363 + 426 2 365 361 364 + 427 1 366 362 361 + 428 2 369 367 368 + 429 2 370 367 368 + 430 2 370 367 369 + 431 2 371 367 368 + 432 2 371 367 369 + 433 2 371 367 370 + 434 1 372 368 367 + 435 2 375 373 374 + 436 2 376 373 374 + 437 2 376 373 375 + 438 2 377 373 374 + 439 2 377 373 375 + 440 2 377 373 376 + 441 1 378 374 373 + 442 2 381 379 380 + 443 2 382 379 380 + 444 2 382 379 381 + 445 2 383 379 380 + 446 2 383 379 381 + 447 2 383 379 382 + 448 1 384 380 379 + +Dihedrals + + 1 1 6 2 1 3 + 2 1 6 2 1 4 + 3 1 6 2 1 5 + 4 1 9 7 8 12 + 5 1 12 8 7 10 + 6 1 12 8 7 11 + 7 1 18 14 13 15 + 8 1 18 14 13 16 + 9 1 18 14 13 17 + 10 1 24 20 19 21 + 11 1 24 20 19 22 + 12 1 24 20 19 23 + 13 1 30 26 25 27 + 14 1 30 26 25 28 + 15 1 30 26 25 29 + 16 1 36 32 31 33 + 17 1 36 32 31 34 + 18 1 36 32 31 35 + 19 1 42 38 37 39 + 20 1 42 38 37 40 + 21 1 42 38 37 41 + 22 1 48 44 43 45 + 23 1 48 44 43 46 + 24 1 48 44 43 47 + 25 1 54 50 49 51 + 26 1 54 50 49 52 + 27 1 54 50 49 53 + 28 1 60 56 55 57 + 29 1 60 56 55 58 + 30 1 60 56 55 59 + 31 1 66 62 61 63 + 32 1 66 62 61 64 + 33 1 66 62 61 65 + 34 1 72 68 67 69 + 35 1 72 68 67 70 + 36 1 72 68 67 71 + 37 1 78 74 73 75 + 38 1 78 74 73 76 + 39 1 78 74 73 77 + 40 1 84 80 79 81 + 41 1 84 80 79 82 + 42 1 84 80 79 83 + 43 1 90 86 85 87 + 44 1 90 86 85 88 + 45 1 90 86 85 89 + 46 1 96 92 91 93 + 47 1 96 92 91 94 + 48 1 96 92 91 95 + 49 1 99 97 98 102 + 50 1 102 98 97 100 + 51 1 102 98 97 101 + 52 1 108 104 103 105 + 53 1 108 104 103 106 + 54 1 108 104 103 107 + 55 1 114 110 109 111 + 56 1 114 110 109 112 + 57 1 114 110 109 113 + 58 1 120 116 115 117 + 59 1 120 116 115 118 + 60 1 120 116 115 119 + 61 1 126 122 121 123 + 62 1 126 122 121 124 + 63 1 126 122 121 125 + 64 1 132 128 127 129 + 65 1 132 128 127 130 + 66 1 132 128 127 131 + 67 1 138 134 133 135 + 68 1 138 134 133 136 + 69 1 138 134 133 137 + 70 1 144 140 139 141 + 71 1 144 140 139 142 + 72 1 144 140 139 143 + 73 1 150 146 145 147 + 74 1 150 146 145 148 + 75 1 150 146 145 149 + 76 1 156 152 151 153 + 77 1 156 152 151 154 + 78 1 156 152 151 155 + 79 1 162 158 157 159 + 80 1 162 158 157 160 + 81 1 162 158 157 161 + 82 1 168 164 163 165 + 83 1 168 164 163 166 + 84 1 168 164 163 167 + 85 1 174 170 169 171 + 86 1 174 170 169 172 + 87 1 174 170 169 173 + 88 1 180 176 175 177 + 89 1 180 176 175 178 + 90 1 180 176 175 179 + 91 1 186 182 181 183 + 92 1 186 182 181 184 + 93 1 186 182 181 185 + 94 1 192 188 187 189 + 95 1 192 188 187 190 + 96 1 192 188 187 191 + 97 1 198 194 193 195 + 98 1 198 194 193 196 + 99 1 198 194 193 197 + 100 1 204 200 199 201 + 101 1 204 200 199 202 + 102 1 204 200 199 203 + 103 1 210 206 205 207 + 104 1 210 206 205 208 + 105 1 210 206 205 209 + 106 1 216 212 211 213 + 107 1 216 212 211 214 + 108 1 216 212 211 215 + 109 1 222 218 217 219 + 110 1 222 218 217 220 + 111 1 222 218 217 221 + 112 1 228 224 223 225 + 113 1 228 224 223 226 + 114 1 228 224 223 227 + 115 1 234 230 229 231 + 116 1 234 230 229 232 + 117 1 234 230 229 233 + 118 1 240 236 235 237 + 119 1 240 236 235 238 + 120 1 240 236 235 239 + 121 1 246 242 241 243 + 122 1 246 242 241 244 + 123 1 246 242 241 245 + 124 1 252 248 247 249 + 125 1 252 248 247 250 + 126 1 252 248 247 251 + 127 1 258 254 253 255 + 128 1 258 254 253 256 + 129 1 258 254 253 257 + 130 1 264 260 259 261 + 131 1 264 260 259 262 + 132 1 264 260 259 263 + 133 1 270 266 265 267 + 134 1 270 266 265 268 + 135 1 270 266 265 269 + 136 1 276 272 271 273 + 137 1 276 272 271 274 + 138 1 276 272 271 275 + 139 1 282 278 277 279 + 140 1 282 278 277 280 + 141 1 282 278 277 281 + 142 1 288 284 283 285 + 143 1 288 284 283 286 + 144 1 288 284 283 287 + 145 1 294 290 289 291 + 146 1 294 290 289 292 + 147 1 294 290 289 293 + 148 1 300 296 295 297 + 149 1 300 296 295 298 + 150 1 300 296 295 299 + 151 1 306 302 301 303 + 152 1 306 302 301 304 + 153 1 306 302 301 305 + 154 1 312 308 307 309 + 155 1 312 308 307 310 + 156 1 312 308 307 311 + 157 1 318 314 313 315 + 158 1 318 314 313 316 + 159 1 318 314 313 317 + 160 1 324 320 319 321 + 161 1 324 320 319 322 + 162 1 324 320 319 323 + 163 1 330 326 325 327 + 164 1 330 326 325 328 + 165 1 330 326 325 329 + 166 1 336 332 331 333 + 167 1 336 332 331 334 + 168 1 336 332 331 335 + 169 1 342 338 337 339 + 170 1 342 338 337 340 + 171 1 342 338 337 341 + 172 1 348 344 343 345 + 173 1 348 344 343 346 + 174 1 348 344 343 347 + 175 1 354 350 349 351 + 176 1 354 350 349 352 + 177 1 354 350 349 353 + 178 1 360 356 355 357 + 179 1 360 356 355 358 + 180 1 360 356 355 359 + 181 1 366 362 361 363 + 182 1 366 362 361 364 + 183 1 366 362 361 365 + 184 1 372 368 367 369 + 185 1 372 368 367 370 + 186 1 372 368 367 371 + 187 1 378 374 373 375 + 188 1 378 374 373 376 + 189 1 378 374 373 377 + 190 1 384 380 379 381 + 191 1 384 380 379 382 + 192 1 384 380 379 383 + +Impropers + diff --git a/examples/dreiding/in.dreiding b/examples/dreiding/in.dreiding new file mode 100644 index 0000000000..4b811248d4 --- /dev/null +++ b/examples/dreiding/in.dreiding @@ -0,0 +1,39 @@ +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.1 b/examples/dreiding/log.dreiding.11Oct11.linux.1 new file mode 100644 index 0000000000..74267f98cc --- /dev/null +++ b/examples/dreiding/log.dreiding.11Oct11.linux.1 @@ -0,0 +1,97 @@ +LAMMPS (10 Oct 2011) +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + 4 = max bonds/atom + 6 = max angles/atom + 3 = max dihedrals/atom + 0 = max impropers/atom + orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697) + 1 by 1 by 1 processor grid + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + 4 = max # of 1-2 neighbors + 3 = max # of 1-3 neighbors + 5 = max # of special neighbors + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 +WARNING: No fixes defined, atoms won't move (verlet.cpp:52) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204) + G vector = 0.142075 + grid = 3 3 3 + stencil order = 5 + RMS precision = 0.000329493 + using double precision FFTs + brick FFT buffer size/proc = 512 27 576 +Memory usage per processor = 7.9487 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = 113.723443 KinEng = 0.000000 Temp = 0.000000 +PotEng = 113.723443 E_bond = 0.535673 E_angle = 1.281880 +E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324 +E_coul = 597.224193 E_long = -361.169476 E_hbond = -69.322152 +C_hbond = 235.000000 Press = -847.552598 Volume = 7447.236335 +Loop time of 0 on 1 procs for 0 steps with 384 atoms + +Pair time (%) = 0 (0) +Bond time (%) = 0 (0) +Kspce time (%) = 0 (0) +Neigh time (%) = 0 (0) +Comm time (%) = 0 (0) +Outpt time (%) = 0 (0) +Other time (%) = 0 (0) + +FFT time (% of Kspce) = 0 (0) +FFT Gflps 3d (1d only) = 0 0 + +Nlocal: 384 ave 384 max 384 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 4637 ave 4637 max 4637 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 101854 ave 101854 max 101854 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 203708 ave 203708 max 203708 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 203708 +Ave neighs/atom = 530.49 +Ave special neighs/atom = 4 +Neighbor list builds = 0 +Dangerous builds = 0 diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.4 b/examples/dreiding/log.dreiding.11Oct11.linux.4 new file mode 100644 index 0000000000..3f0ac1c40d --- /dev/null +++ b/examples/dreiding/log.dreiding.11Oct11.linux.4 @@ -0,0 +1,121 @@ +LAMMPS (10 Oct 2011) +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + 4 = max bonds/atom + 6 = max angles/atom + 3 = max dihedrals/atom + 0 = max impropers/atom + orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697) + 2 by 1 by 2 processor grid + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + 4 = max # of 1-2 neighbors + 3 = max # of 1-3 neighbors + 5 = max # of special neighbors + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 +WARNING: No fixes defined, atoms won't move (verlet.cpp:52) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204) + G vector = 0.142075 + grid = 3 3 3 + stencil order = 5 + RMS precision = 0.000329493 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.143211 + grid = 3 3 3 + stencil order = 4 + RMS precision = 0.000315601 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.140124 + grid = 3 3 3 + stencil order = 3 + RMS precision = 0.000354326 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.127333 + grid = 3 3 3 + stencil order = 2 + RMS precision = 0.00055716 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.113516 + grid = 9 9 9 + stencil order = 1 + RMS precision = 0.000864991 + using double precision FFTs + brick FFT buffer size/proc = 360 243 360 +Memory usage per processor = 6.52575 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = 118.484313 KinEng = 0.000000 Temp = 0.000000 +PotEng = 118.484313 E_bond = 0.535673 E_angle = 1.281880 +E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324 +E_coul = 529.430008 E_long = -288.614421 E_hbond = -69.322152 +C_hbond = 235.000000 Press = -803.848888 Volume = 7447.236335 +Loop time of 1.43051e-06 on 4 procs for 0 steps with 384 atoms + +Pair time (%) = 0 (0) +Bond time (%) = 0 (0) +Kspce time (%) = 0 (0) +Neigh time (%) = 0 (0) +Comm time (%) = 0 (0) +Outpt time (%) = 0 (0) +Other time (%) = 1.43051e-06 (100) + +FFT time (% of Kspce) = 0 (0) +FFT Gflps 3d (1d only) = 0 0 + +Nlocal: 96 ave 104 max 87 min +Histogram: 1 1 0 0 0 0 0 0 0 2 +Nghost: 3063.25 ave 3108 max 3024 min +Histogram: 1 0 1 0 0 0 1 0 0 1 +Neighs: 25463.5 ave 28799 max 22471 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +FullNghs: 50927 ave 55516 max 46073 min +Histogram: 1 1 0 0 0 0 0 0 0 2 + +Total # of neighbors = 203708 +Ave neighs/atom = 530.49 +Ave special neighs/atom = 4 +Neighbor list builds = 0 +Dangerous builds = 0 From 2e2abb3a7271f245fdd267d89dee1781bafc2c30 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 16:36:40 +0000 Subject: [PATCH 189/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7063 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 9da39c4204..4fc791ad6b 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "10 Oct 2011" +#define LAMMPS_VERSION "11 Oct 2011" From e6a0e39b5070a1d0417bf986550d6dea840e4163 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:03:52 +0000 Subject: [PATCH 190/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7065 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/KSPACE/pppm.cpp | 24 +++++++------- src/KSPACE/pppm.h | 1 - src/KSPACE/pppm_cg.cpp | 9 ++++-- src/MANYBODY/pair_tersoff.cpp | 34 ++++--------------- src/MANYBODY/pair_tersoff.h | 54 +++++++++++++++++++++++-------- src/MANYBODY/pair_tersoff_zbl.cpp | 6 ++-- src/USER-EWALDN/math_vector.h | 1 + 7 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index cc92e1719f..221778e6ee 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -35,7 +35,10 @@ #include "memory.h" #include "error.h" +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; #define MAXORDER 7 #define OFFSET 16384 @@ -58,7 +61,6 @@ PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) if (narg < 1) error->all(FLERR,"Illegal kspace_style pppm command"); precision = atof(arg[0]); - PI = 4.0*atan(1.0); nfactors = 3; factors = new int[nfactors]; @@ -520,9 +522,9 @@ void PPPM::setup() delvolinv = delxinv*delyinv*delzinv; - double unitkx = (2.0*PI/xprd); - double unitky = (2.0*PI/yprd); - double unitkz = (2.0*PI/zprd_slab); + double unitkx = (2.0*MY_PI/xprd); + double unitky = (2.0*MY_PI/yprd); + double unitkz = (2.0*MY_PI/zprd_slab); // fkx,fky,fkz for my FFT grid pts @@ -581,11 +583,11 @@ void PPPM::setup() double sum1,dot1,dot2; double numerator,denominator; - int nbx = static_cast ((g_ewald*xprd/(PI*nx_pppm)) * + int nbx = static_cast ((g_ewald*xprd/(MY_PI*nx_pppm)) * pow(-log(EPS_HOC),0.25)); - int nby = static_cast ((g_ewald*yprd/(PI*ny_pppm)) * + int nby = static_cast ((g_ewald*yprd/(MY_PI*ny_pppm)) * pow(-log(EPS_HOC),0.25)); - int nbz = static_cast ((g_ewald*zprd_slab/(PI*nz_pppm)) * + int nbz = static_cast ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) * pow(-log(EPS_HOC),0.25)); double form = 1.0; @@ -708,7 +710,7 @@ void PPPM::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } @@ -1027,7 +1029,7 @@ double PPPM::rms(double h, double prd, bigint natoms, for (int m = 0; m < order; m++) sum += acons[order][m] * pow(h*g_ewald,2.0*m); double value = q2 * pow(h*g_ewald,order) * - sqrt(g_ewald*prd*sqrt(2.0*PI)*sum/natoms) / (prd*prd); + sqrt(g_ewald*prd*sqrt(2.0*MY_PI)*sum/natoms) / (prd*prd); return value; } @@ -1873,13 +1875,13 @@ void PPPM::slabcorr(int eflag) // compute corrections - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; + double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume; if (eflag) energy += qqrd2e*scale * e_slabcorr; // add on force corrections - double ffact = -4.0*PI*dipole_all/volume; + double ffact = -4.0*MY_PI*dipole_all/volume; double **f = atom->f; for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact; diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h index 982b8f7c9e..e2a58e8804 100644 --- a/src/KSPACE/pppm.h +++ b/src/KSPACE/pppm.h @@ -47,7 +47,6 @@ class PPPM : public KSpace { protected: int me,nprocs; - double PI; double precision; int nfactors; int *factors; diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp index 12860f7aed..5f57715f9f 100644 --- a/src/KSPACE/pppm_cg.cpp +++ b/src/KSPACE/pppm_cg.cpp @@ -26,7 +26,10 @@ #include "memory.h" #include "pppm_cg.h" +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; #define OFFSET 16384 #define SMALLQ 0.00001 @@ -176,7 +179,7 @@ void PPPMCG::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } @@ -372,13 +375,13 @@ void PPPMCG::slabcorr(int eflag) // compute corrections - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; + double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume; if (eflag) energy += qqrd2e*scale * e_slabcorr; // add on force corrections - double ffact = -4.0*PI*dipole_all/volume * qqrd2e * scale; + double ffact = -4.0*MY_PI*dipole_all/volume * qqrd2e * scale; double **f = atom->f; for (int j = 0; j < num_charged; j++) { diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index bd50ec9bd3..7771bb1982 100755 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -29,7 +29,10 @@ #include "memory.h" #include "error.h" +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; #define MAXLINE 1024 #define DELTA 4 @@ -41,10 +44,6 @@ PairTersoff::PairTersoff(LAMMPS *lmp) : Pair(lmp) single_enable = 0; one_coeff = 1; - PI = 4.0*atan(1.0); - PI2 = 2.0*atan(1.0); - PI4 = atan(1.0); - nelements = 0; elements = NULL; nparams = maxparam = 0; @@ -634,7 +633,7 @@ double PairTersoff::ters_fc(double r, Param *param) if (r < ters_R-ters_D) return 1.0; if (r > ters_R+ters_D) return 0.0; - return 0.5*(1.0 - sin(PI2*(r - ters_R)/ters_D)); + return 0.5*(1.0 - sin(MY_PI2*(r - ters_R)/ters_D)); } /* ---------------------------------------------------------------------- */ @@ -646,7 +645,7 @@ double PairTersoff::ters_fc_d(double r, Param *param) if (r < ters_R-ters_D) return 0.0; if (r > ters_R+ters_D) return 0.0; - return -(PI4/ters_D) * cos(PI2*(r - ters_R)/ters_D); + return -(MY_PI4/ters_D) * cos(MY_PI2*(r - ters_R)/ters_D); } /* ---------------------------------------------------------------------- */ @@ -700,27 +699,6 @@ double PairTersoff::ters_bij_d(double zeta, Param *param) /* ---------------------------------------------------------------------- */ -double PairTersoff::ters_gijk(double costheta, Param *param) -{ - double ters_c = param->c; - double ters_d = param->d; - - return param->gamma*(1.0 + pow(ters_c/ters_d,2.0) - - pow(ters_c,2.0) / (pow(ters_d,2.0) + pow(param->h - costheta,2.0))); -}; - -/* ---------------------------------------------------------------------- */ - -double PairTersoff::ters_gijk_d(double costheta, Param *param) -{ - double numerator = -2.0 * pow(param->c,2) * (param->h - costheta); - double denominator = pow(pow(param->d,2.0) + - pow(param->h - costheta,2.0),2.0); - return param->gamma*numerator/denominator; -} - -/* ---------------------------------------------------------------------- */ - void PairTersoff::ters_zetaterm_d(double prefactor, double *rij_hat, double rij, double *rik_hat, double rik, @@ -794,4 +772,4 @@ void PairTersoff::costheta_d(double *rij_hat, double rij, vec3_scale(1.0/rik,drk,drk); vec3_add(drj,drk,dri); vec3_scale(-1.0,dri,dri); -}; +} diff --git a/src/MANYBODY/pair_tersoff.h b/src/MANYBODY/pair_tersoff.h index 49d3079286..92dbe635bd 100755 --- a/src/MANYBODY/pair_tersoff.h +++ b/src/MANYBODY/pair_tersoff.h @@ -28,7 +28,7 @@ class PairTersoff : public Pair { public: PairTersoff(class LAMMPS *); virtual ~PairTersoff(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); @@ -49,22 +49,22 @@ class PairTersoff : public Pair { double ZBLcut,ZBLexpscale; }; - double PI,PI2,PI4; - double cutmax; // max cutoff for all elements - int nelements; // # of unique elements + Param *params; // parameter set for an I-J-K interaction char **elements; // names of unique elements int ***elem2param; // mapping from element triplets to parameters int *map; // mapping from atom types to elements + double cutmax; // max cutoff for all elements + int nelements; // # of unique elements int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets - Param *params; // parameter set for an I-J-K interaction void allocate(); virtual void read_file(char *); void setup(); virtual void repulsive(Param *, double, double &, int, double &); double zeta(Param *, double, double, double *, double *); - void force_zeta(Param *, double, double, double &, double &, int, double &); + virtual void force_zeta(Param *, double, double, double &, + double &, int, double &); void attractive(Param *, double, double, double, double *, double *, double *, double *, double *); @@ -74,26 +74,52 @@ class PairTersoff : public Pair { virtual double ters_fa_d(double, Param *); double ters_bij(double, Param *); double ters_bij_d(double, Param *); - double ters_gijk(double, Param *); - double ters_gijk_d(double, Param *); + void ters_zetaterm_d(double, double *, double, double *, double, double *, double *, double *, Param *); void costheta_d(double *, double, double *, double, double *, double *, double *); - // vector functions, inline for efficiency + // inlined functions for efficiency - inline double vec3_dot(double *x, double *y) { + inline double ters_gijk(const double costheta, + const Param * const param) const { + const double ters_c = param->c * param->c; + const double ters_d = param->d * param->d; + const double hcth = param->h - costheta; + + return param->gamma*(1.0 + ters_c/ters_d - ters_c / (ters_d + hcth*hcth)); + } + + inline double ters_gijk_d(const double costheta, + const Param * const param) const { + const double ters_c = param->c * param->c; + const double ters_d = param->d * param->d; + const double hcth = param->h - costheta; + const double numerator = -2.0 * ters_c * hcth; + const double denominator = 1.0/(ters_d + hcth*hcth); + return param->gamma*numerator*denominator*denominator; + } + + inline double vec3_dot(const double x[3], const double y[3]) const { return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]; } - inline void vec3_add(double *x, double *y, double *z) { + + inline void vec3_add(const double x[3], const double y[3], + double * const z) const { z[0] = x[0]+y[0]; z[1] = x[1]+y[1]; z[2] = x[2]+y[2]; } - inline void vec3_scale(double k, double *x, double *y) { + + inline void vec3_scale(const double k, const double x[3], + double y[3]) const { y[0] = k*x[0]; y[1] = k*x[1]; y[2] = k*x[2]; } - inline void vec3_scaleadd(double k, double *x, double *y, double *z) { - z[0] = k*x[0]+y[0]; z[1] = k*x[1]+y[1]; z[2] = k*x[2]+y[2]; + + inline void vec3_scaleadd(const double k, const double x[3], + const double y[3], double * const z) const { + z[0] = k*x[0]+y[0]; + z[1] = k*x[1]+y[1]; + z[2] = k*x[2]+y[2]; } }; diff --git a/src/MANYBODY/pair_tersoff_zbl.cpp b/src/MANYBODY/pair_tersoff_zbl.cpp index 90ccfd9c11..a4f6ee3edd 100644 --- a/src/MANYBODY/pair_tersoff_zbl.cpp +++ b/src/MANYBODY/pair_tersoff_zbl.cpp @@ -31,7 +31,9 @@ #include "memory.h" #include "error.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXLINE 1024 #define DELTA 4 @@ -224,7 +226,7 @@ void PairTersoffZBL::repulsive(Param *param, double rsq, double &fforce, double esq = pow(global_e,2.0); double a_ij = (0.8854*global_a_0) / (pow(param->Z_i,0.23) + pow(param->Z_j,0.23)); - double premult = (param->Z_i * param->Z_j * esq)/(4.0*PI*global_epsilon_0); + double premult = (param->Z_i * param->Z_j * esq)/(4.0*MY_PI*global_epsilon_0); double r_ov_a = r/a_ij; double phi = 0.1818*exp(-3.2*r_ov_a) + 0.5099*exp(-0.9423*r_ov_a) + 0.2802*exp(-0.4029*r_ov_a) + 0.02817*exp(-0.2016*r_ov_a); @@ -232,7 +234,7 @@ void PairTersoffZBL::repulsive(Param *param, double rsq, double &fforce, 0.9423*0.5099*exp(-0.9423*r_ov_a) - 0.4029*0.2802*exp(-0.4029*r_ov_a) - 0.2016*0.02817*exp(-0.2016*r_ov_a)); - double fforce_ZBL = premult*-pow(r,-2.0)* phi + premult*pow(r,-1.0)*dphi; + double fforce_ZBL = premult*-phi/rsq + premult*dphi/r; double eng_ZBL = premult*(1.0/r)*phi; // combine two parts with smoothing by Fermi-like function diff --git a/src/USER-EWALDN/math_vector.h b/src/USER-EWALDN/math_vector.h index 90fc7ee464..b7473b5d89 100644 --- a/src/USER-EWALDN/math_vector.h +++ b/src/USER-EWALDN/math_vector.h @@ -19,6 +19,7 @@ #define LMP_MATH_VECTOR_H #include "math.h" +#include "string.h" #define VECTOR_NULL {0, 0, 0} #define SHAPE_NULL {0, 0, 0, 0, 0, 0} From 90a5d2b322bf384b89d7903647c82005483ec5f9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:11:58 +0000 Subject: [PATCH 191/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7066 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-OMP/Install.sh | 40 +- src/USER-OMP/Package.sh | 15 +- src/USER-OMP/dihedral_charmm_omp.cpp | 328 ++++++++++ src/USER-OMP/dihedral_charmm_omp.h | 48 ++ src/USER-OMP/dihedral_class2_omp.cpp | 532 ++++++++++++++++ src/USER-OMP/dihedral_class2_omp.h | 48 ++ .../dihedral_cosine_shift_exp_omp.cpp | 263 ++++++++ src/USER-OMP/dihedral_cosine_shift_exp_omp.h | 48 ++ src/USER-OMP/dihedral_harmonic_omp.cpp | 270 ++++++++ src/USER-OMP/dihedral_harmonic_omp.h | 48 ++ src/USER-OMP/dihedral_helix_omp.cpp | 280 +++++++++ src/USER-OMP/dihedral_helix_omp.h | 48 ++ src/USER-OMP/dihedral_multi_harmonic_omp.cpp | 269 ++++++++ src/USER-OMP/dihedral_multi_harmonic_omp.h | 48 ++ src/USER-OMP/dihedral_opls_omp.cpp | 286 +++++++++ src/USER-OMP/dihedral_opls_omp.h | 48 ++ src/USER-OMP/fix_gravity_omp.cpp | 114 ++++ src/USER-OMP/fix_gravity_omp.h | 38 ++ src/USER-OMP/fix_nve_sphere_omp.cpp | 140 +++++ src/USER-OMP/fix_nve_sphere_omp.h | 39 ++ src/USER-OMP/fix_qeq_comb_omp.cpp | 166 +++++ src/USER-OMP/fix_qeq_comb_omp.h | 32 + src/USER-OMP/fix_shear_history_omp.cpp | 150 +++++ src/USER-OMP/fix_shear_history_omp.h | 38 ++ src/USER-OMP/pair_adp_omp.cpp | 404 ++++++++++++ src/USER-OMP/pair_adp_omp.h | 49 ++ src/USER-OMP/pair_born_coul_long_omp.cpp | 199 ++++++ src/USER-OMP/pair_born_coul_long_omp.h | 48 ++ src/USER-OMP/pair_born_omp.cpp | 163 +++++ src/USER-OMP/pair_born_omp.h | 48 ++ src/USER-OMP/pair_buck_coul_cut_omp.cpp | 182 ++++++ src/USER-OMP/pair_buck_coul_cut_omp.h | 48 ++ src/USER-OMP/pair_buck_coul_long_omp.cpp | 198 ++++++ src/USER-OMP/pair_buck_coul_long_omp.h | 48 ++ src/USER-OMP/pair_buck_coul_omp.cpp | 230 +++++++ src/USER-OMP/pair_buck_coul_omp.h | 48 ++ src/USER-OMP/pair_buck_omp.cpp | 165 +++++ src/USER-OMP/pair_buck_omp.h | 48 ++ src/USER-OMP/pair_cdeam_omp.cpp | 545 +++++++++++++++++ src/USER-OMP/pair_cdeam_omp.h | 66 ++ src/USER-OMP/pair_colloid_omp.cpp | 223 +++++++ src/USER-OMP/pair_colloid_omp.h | 48 ++ src/USER-OMP/pair_comb_omp.cpp | 540 ++++++++++++++++ src/USER-OMP/pair_comb_omp.h | 45 ++ src/USER-OMP/pair_coul_cut_omp.cpp | 162 +++++ src/USER-OMP/pair_coul_cut_omp.h | 48 ++ src/USER-OMP/pair_coul_debye_omp.cpp | 163 +++++ src/USER-OMP/pair_coul_debye_omp.h | 48 ++ src/USER-OMP/pair_coul_long_omp.cpp | 201 ++++++ src/USER-OMP/pair_coul_long_omp.h | 48 ++ src/USER-OMP/pair_dipole_cut_omp.cpp | 288 +++++++++ src/USER-OMP/pair_dipole_cut_omp.h | 48 ++ src/USER-OMP/pair_dipole_sf_omp.cpp | 320 ++++++++++ src/USER-OMP/pair_dipole_sf_omp.h | 48 ++ src/USER-OMP/pair_dpd_omp.cpp | 212 +++++++ src/USER-OMP/pair_dpd_omp.h | 52 ++ src/USER-OMP/pair_dpd_tstat_omp.cpp | 214 +++++++ src/USER-OMP/pair_dpd_tstat_omp.h | 52 ++ src/USER-OMP/pair_eam_alloy_omp.cpp | 323 ++++++++++ src/USER-OMP/pair_eam_alloy_omp.h | 43 ++ src/USER-OMP/pair_eam_fs_omp.cpp | 332 ++++++++++ src/USER-OMP/pair_eam_fs_omp.h | 43 ++ src/USER-OMP/pair_eam_omp.cpp | 303 +++++++++ src/USER-OMP/pair_eam_omp.h | 48 ++ src/USER-OMP/pair_edip_omp.cpp | 485 +++++++++++++++ src/USER-OMP/pair_edip_omp.h | 43 ++ src/USER-OMP/pair_eim_omp.cpp | 365 +++++++++++ src/USER-OMP/pair_eim_omp.h | 48 ++ src/USER-OMP/pair_gauss_omp.cpp | 170 ++++++ src/USER-OMP/pair_gauss_omp.h | 48 ++ src/USER-OMP/pair_gayberne_omp.cpp | 227 +++++++ src/USER-OMP/pair_gayberne_omp.h | 48 ++ src/USER-OMP/pair_gran_hertz_history_omp.cpp | 298 +++++++++ src/USER-OMP/pair_gran_hertz_history_omp.h | 48 ++ src/USER-OMP/pair_gran_hooke_history_omp.cpp | 301 +++++++++ src/USER-OMP/pair_gran_hooke_history_omp.h | 48 ++ src/USER-OMP/pair_gran_hooke_omp.cpp | 240 ++++++++ src/USER-OMP/pair_gran_hooke_omp.h | 48 ++ src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp | 299 +++++++++ src/USER-OMP/pair_hbond_dreiding_lj_omp.h | 52 ++ .../pair_hbond_dreiding_morse_omp.cpp | 297 +++++++++ src/USER-OMP/pair_hbond_dreiding_morse_omp.h | 52 ++ src/USER-OMP/pair_lj96_cut_omp.cpp | 162 +++++ src/USER-OMP/pair_lj96_cut_omp.h | 48 ++ ...air_lj_charmm_coul_charmm_implicit_omp.cpp | 213 +++++++ .../pair_lj_charmm_coul_charmm_implicit_omp.h | 48 ++ .../pair_lj_charmm_coul_charmm_omp.cpp | 213 +++++++ src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h | 48 ++ src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp | 234 +++++++ src/USER-OMP/pair_lj_charmm_coul_long_omp.h | 48 ++ src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp | 185 ++++++ src/USER-OMP/pair_lj_class2_coul_cut_omp.h | 48 ++ src/USER-OMP/pair_lj_class2_coul_long_omp.cpp | 201 ++++++ src/USER-OMP/pair_lj_class2_coul_long_omp.h | 48 ++ src/USER-OMP/pair_lj_class2_omp.cpp | 162 +++++ src/USER-OMP/pair_lj_class2_omp.h | 48 ++ src/USER-OMP/pair_lj_coul_omp.cpp | 234 +++++++ src/USER-OMP/pair_lj_coul_omp.h | 48 ++ src/USER-OMP/pair_lj_cubic_omp.cpp | 173 ++++++ src/USER-OMP/pair_lj_cubic_omp.h | 48 ++ src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp | 183 ++++++ src/USER-OMP/pair_lj_cut_coul_cut_omp.h | 48 ++ src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp | 186 ++++++ src/USER-OMP/pair_lj_cut_coul_debye_omp.h | 48 ++ src/USER-OMP/pair_lj_cut_coul_long_omp.cpp | 220 +++++++ src/USER-OMP/pair_lj_cut_coul_long_omp.h | 48 ++ .../pair_lj_cut_coul_long_tip4p_omp.cpp | 462 ++++++++++++++ .../pair_lj_cut_coul_long_tip4p_omp.h | 57 ++ src/USER-OMP/pair_lj_cut_omp.cpp | 5 +- src/USER-OMP/pair_lj_expand_omp.cpp | 164 +++++ src/USER-OMP/pair_lj_expand_omp.h | 48 ++ .../pair_lj_gromacs_coul_gromacs_omp.cpp | 210 +++++++ .../pair_lj_gromacs_coul_gromacs_omp.h | 48 ++ src/USER-OMP/pair_lj_gromacs_omp.cpp | 172 ++++++ src/USER-OMP/pair_lj_gromacs_omp.h | 48 ++ src/USER-OMP/pair_lj_sf_omp.cpp | 163 +++++ src/USER-OMP/pair_lj_sf_omp.h | 48 ++ src/USER-OMP/pair_lj_smooth_omp.cpp | 176 ++++++ src/USER-OMP/pair_lj_smooth_omp.h | 48 ++ src/USER-OMP/pair_lubricate_omp.cpp | 328 ++++++++++ src/USER-OMP/pair_lubricate_omp.h | 52 ++ src/USER-OMP/pair_morse_omp.cpp | 160 +++++ src/USER-OMP/pair_morse_omp.h | 48 ++ src/USER-OMP/pair_peri_lps_omp.cpp | 456 ++++++++++++++ src/USER-OMP/pair_peri_lps_omp.h | 52 ++ src/USER-OMP/pair_peri_pmb_omp.cpp | 312 ++++++++++ src/USER-OMP/pair_peri_pmb_omp.h | 48 ++ src/USER-OMP/pair_rebo_omp.cpp | 33 + src/USER-OMP/pair_rebo_omp.h | 36 ++ src/USER-OMP/pair_resquared_omp.cpp | 210 +++++++ src/USER-OMP/pair_resquared_omp.h | 48 ++ src/USER-OMP/pair_soft_omp.cpp | 160 +++++ src/USER-OMP/pair_soft_omp.h | 48 ++ src/USER-OMP/pair_sw_omp.cpp | 212 +++++++ src/USER-OMP/pair_sw_omp.h | 48 ++ src/USER-OMP/pair_table_omp.cpp | 202 ++++++ src/USER-OMP/pair_table_omp.h | 48 ++ src/USER-OMP/pair_tersoff_omp.cpp | 252 ++++++++ src/USER-OMP/pair_tersoff_omp.h | 43 ++ src/USER-OMP/pair_tersoff_zbl_omp.cpp | 296 +++++++++ src/USER-OMP/pair_tersoff_zbl_omp.h | 45 ++ src/USER-OMP/pair_yukawa_colloid_omp.cpp | 164 +++++ src/USER-OMP/pair_yukawa_colloid_omp.h | 48 ++ src/USER-OMP/pair_yukawa_omp.cpp | 162 +++++ src/USER-OMP/pair_yukawa_omp.h | 48 ++ src/USER-OMP/thr_omp.cpp | 577 +++++++++++++++--- src/USER-OMP/thr_omp.h | 41 +- 147 files changed, 21457 insertions(+), 105 deletions(-) create mode 100644 src/USER-OMP/dihedral_charmm_omp.cpp create mode 100644 src/USER-OMP/dihedral_charmm_omp.h create mode 100644 src/USER-OMP/dihedral_class2_omp.cpp create mode 100644 src/USER-OMP/dihedral_class2_omp.h create mode 100644 src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp create mode 100644 src/USER-OMP/dihedral_cosine_shift_exp_omp.h create mode 100644 src/USER-OMP/dihedral_harmonic_omp.cpp create mode 100644 src/USER-OMP/dihedral_harmonic_omp.h create mode 100644 src/USER-OMP/dihedral_helix_omp.cpp create mode 100644 src/USER-OMP/dihedral_helix_omp.h create mode 100644 src/USER-OMP/dihedral_multi_harmonic_omp.cpp create mode 100644 src/USER-OMP/dihedral_multi_harmonic_omp.h create mode 100644 src/USER-OMP/dihedral_opls_omp.cpp create mode 100644 src/USER-OMP/dihedral_opls_omp.h create mode 100644 src/USER-OMP/fix_gravity_omp.cpp create mode 100644 src/USER-OMP/fix_gravity_omp.h create mode 100644 src/USER-OMP/fix_nve_sphere_omp.cpp create mode 100644 src/USER-OMP/fix_nve_sphere_omp.h create mode 100644 src/USER-OMP/fix_qeq_comb_omp.cpp create mode 100644 src/USER-OMP/fix_qeq_comb_omp.h create mode 100644 src/USER-OMP/fix_shear_history_omp.cpp create mode 100644 src/USER-OMP/fix_shear_history_omp.h create mode 100644 src/USER-OMP/pair_adp_omp.cpp create mode 100644 src/USER-OMP/pair_adp_omp.h create mode 100644 src/USER-OMP/pair_born_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_born_coul_long_omp.h create mode 100644 src/USER-OMP/pair_born_omp.cpp create mode 100644 src/USER-OMP/pair_born_omp.h create mode 100644 src/USER-OMP/pair_buck_coul_cut_omp.cpp create mode 100644 src/USER-OMP/pair_buck_coul_cut_omp.h create mode 100644 src/USER-OMP/pair_buck_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_buck_coul_long_omp.h create mode 100644 src/USER-OMP/pair_buck_coul_omp.cpp create mode 100644 src/USER-OMP/pair_buck_coul_omp.h create mode 100644 src/USER-OMP/pair_buck_omp.cpp create mode 100644 src/USER-OMP/pair_buck_omp.h create mode 100644 src/USER-OMP/pair_cdeam_omp.cpp create mode 100644 src/USER-OMP/pair_cdeam_omp.h create mode 100644 src/USER-OMP/pair_colloid_omp.cpp create mode 100644 src/USER-OMP/pair_colloid_omp.h create mode 100644 src/USER-OMP/pair_comb_omp.cpp create mode 100644 src/USER-OMP/pair_comb_omp.h create mode 100644 src/USER-OMP/pair_coul_cut_omp.cpp create mode 100644 src/USER-OMP/pair_coul_cut_omp.h create mode 100644 src/USER-OMP/pair_coul_debye_omp.cpp create mode 100644 src/USER-OMP/pair_coul_debye_omp.h create mode 100644 src/USER-OMP/pair_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_coul_long_omp.h create mode 100644 src/USER-OMP/pair_dipole_cut_omp.cpp create mode 100644 src/USER-OMP/pair_dipole_cut_omp.h create mode 100644 src/USER-OMP/pair_dipole_sf_omp.cpp create mode 100644 src/USER-OMP/pair_dipole_sf_omp.h create mode 100644 src/USER-OMP/pair_dpd_omp.cpp create mode 100644 src/USER-OMP/pair_dpd_omp.h create mode 100644 src/USER-OMP/pair_dpd_tstat_omp.cpp create mode 100644 src/USER-OMP/pair_dpd_tstat_omp.h create mode 100644 src/USER-OMP/pair_eam_alloy_omp.cpp create mode 100644 src/USER-OMP/pair_eam_alloy_omp.h create mode 100644 src/USER-OMP/pair_eam_fs_omp.cpp create mode 100644 src/USER-OMP/pair_eam_fs_omp.h create mode 100644 src/USER-OMP/pair_eam_omp.cpp create mode 100644 src/USER-OMP/pair_eam_omp.h create mode 100644 src/USER-OMP/pair_edip_omp.cpp create mode 100644 src/USER-OMP/pair_edip_omp.h create mode 100644 src/USER-OMP/pair_eim_omp.cpp create mode 100644 src/USER-OMP/pair_eim_omp.h create mode 100644 src/USER-OMP/pair_gauss_omp.cpp create mode 100644 src/USER-OMP/pair_gauss_omp.h create mode 100644 src/USER-OMP/pair_gayberne_omp.cpp create mode 100644 src/USER-OMP/pair_gayberne_omp.h create mode 100644 src/USER-OMP/pair_gran_hertz_history_omp.cpp create mode 100644 src/USER-OMP/pair_gran_hertz_history_omp.h create mode 100644 src/USER-OMP/pair_gran_hooke_history_omp.cpp create mode 100644 src/USER-OMP/pair_gran_hooke_history_omp.h create mode 100644 src/USER-OMP/pair_gran_hooke_omp.cpp create mode 100644 src/USER-OMP/pair_gran_hooke_omp.h create mode 100644 src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp create mode 100644 src/USER-OMP/pair_hbond_dreiding_lj_omp.h create mode 100644 src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp create mode 100644 src/USER-OMP/pair_hbond_dreiding_morse_omp.h create mode 100644 src/USER-OMP/pair_lj96_cut_omp.cpp create mode 100644 src/USER-OMP/pair_lj96_cut_omp.h create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h create mode 100644 src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_lj_charmm_coul_long_omp.h create mode 100644 src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp create mode 100644 src/USER-OMP/pair_lj_class2_coul_cut_omp.h create mode 100644 src/USER-OMP/pair_lj_class2_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_lj_class2_coul_long_omp.h create mode 100644 src/USER-OMP/pair_lj_class2_omp.cpp create mode 100644 src/USER-OMP/pair_lj_class2_omp.h create mode 100644 src/USER-OMP/pair_lj_coul_omp.cpp create mode 100644 src/USER-OMP/pair_lj_coul_omp.h create mode 100644 src/USER-OMP/pair_lj_cubic_omp.cpp create mode 100644 src/USER-OMP/pair_lj_cubic_omp.h create mode 100644 src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp create mode 100644 src/USER-OMP/pair_lj_cut_coul_cut_omp.h create mode 100644 src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp create mode 100644 src/USER-OMP/pair_lj_cut_coul_debye_omp.h create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_omp.cpp create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_omp.h create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h create mode 100644 src/USER-OMP/pair_lj_expand_omp.cpp create mode 100644 src/USER-OMP/pair_lj_expand_omp.h create mode 100644 src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp create mode 100644 src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h create mode 100644 src/USER-OMP/pair_lj_gromacs_omp.cpp create mode 100644 src/USER-OMP/pair_lj_gromacs_omp.h create mode 100644 src/USER-OMP/pair_lj_sf_omp.cpp create mode 100644 src/USER-OMP/pair_lj_sf_omp.h create mode 100644 src/USER-OMP/pair_lj_smooth_omp.cpp create mode 100644 src/USER-OMP/pair_lj_smooth_omp.h create mode 100644 src/USER-OMP/pair_lubricate_omp.cpp create mode 100644 src/USER-OMP/pair_lubricate_omp.h create mode 100644 src/USER-OMP/pair_morse_omp.cpp create mode 100644 src/USER-OMP/pair_morse_omp.h create mode 100644 src/USER-OMP/pair_peri_lps_omp.cpp create mode 100644 src/USER-OMP/pair_peri_lps_omp.h create mode 100644 src/USER-OMP/pair_peri_pmb_omp.cpp create mode 100644 src/USER-OMP/pair_peri_pmb_omp.h create mode 100644 src/USER-OMP/pair_rebo_omp.cpp create mode 100644 src/USER-OMP/pair_rebo_omp.h create mode 100644 src/USER-OMP/pair_resquared_omp.cpp create mode 100644 src/USER-OMP/pair_resquared_omp.h create mode 100644 src/USER-OMP/pair_soft_omp.cpp create mode 100644 src/USER-OMP/pair_soft_omp.h create mode 100644 src/USER-OMP/pair_sw_omp.cpp create mode 100644 src/USER-OMP/pair_sw_omp.h create mode 100644 src/USER-OMP/pair_table_omp.cpp create mode 100644 src/USER-OMP/pair_table_omp.h create mode 100644 src/USER-OMP/pair_tersoff_omp.cpp create mode 100644 src/USER-OMP/pair_tersoff_omp.h create mode 100644 src/USER-OMP/pair_tersoff_zbl_omp.cpp create mode 100644 src/USER-OMP/pair_tersoff_zbl_omp.h create mode 100644 src/USER-OMP/pair_yukawa_colloid_omp.cpp create mode 100644 src/USER-OMP/pair_yukawa_colloid_omp.h create mode 100644 src/USER-OMP/pair_yukawa_omp.cpp create mode 100644 src/USER-OMP/pair_yukawa_omp.h diff --git a/src/USER-OMP/Install.sh b/src/USER-OMP/Install.sh index 6af8599524..db0beb5218 100644 --- a/src/USER-OMP/Install.sh +++ b/src/USER-OMP/Install.sh @@ -1,32 +1,20 @@ # Install/unInstall package files in LAMMPS # do not install child files if parent does not exist -if (test $1 = 1) then +for file in *_omp.cpp *_omp.h; do + # let us see if the "rain man" can count the toothpicks... + ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,` -# if (test -e ../pair_lj_cut_coul_long.cpp) then -# cp pair_lj_cut_coul_long_omp.cpp .. -# cp pair_lj_cut_coul_long_omp.h .. -# fi + if (test $1 = 1) then + if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then + : # always install those files. + elif (test ! -e ../$ofile) then + continue + fi - cp pair_lj_cut_omp.cpp .. - - cp thr_omp.cpp .. - - cp pair_lj_cut_omp.h .. - - cp thr_omp.h .. - -elif (test $1 = 0) then - -# rm -f ../pair_lj_cut_coul_long_omp.cpp - rm -f ../pair_lj_cut_omp.cpp - - rm -f ../thr_omp.cpp - -# rm -f ../pair_lj_cut_coul_long_omp.h - rm -f ../pair_lj_cut_omp.h - - rm -f ../thr_omp.h - -fi + cp $file .. + elif (test $1 = 0) then + rm -f ../$file + fi +done diff --git a/src/USER-OMP/Package.sh b/src/USER-OMP/Package.sh index ecd2ebee10..5a004c9187 100644 --- a/src/USER-OMP/Package.sh +++ b/src/USER-OMP/Package.sh @@ -1,15 +1,22 @@ -#/bin/sh # Update package files in LAMMPS -# copy package file to src if it doesn't exists or is different -# do not copy gayberne files if non-GPU version does not exist +# cp package file to src if doesn't exist or is different +# do not copy certain files if non-OMP versions do not exist +# do remove OpenMP style files that have no matching +# non-OpenMP version installed, e.g. after a package has been removed + for file in *_omp.cpp *_omp.h; do # let us see if the "rain man" can count the toothpicks... ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,` if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then - : # do check for those files. + : # always check for those files. elif (test ! -e ../$ofile) then + if (test -e ../$file) then + echo " removing src/$file" + rm -f ../$file + fi continue fi + if (test ! -e ../$file) then echo " creating src/$file" cp $file .. diff --git a/src/USER-OMP/dihedral_charmm_omp.cpp b/src/USER-OMP/dihedral_charmm_omp.cpp new file mode 100644 index 0000000000..63bfc43270 --- /dev/null +++ b/src/USER-OMP/dihedral_charmm_omp.cpp @@ -0,0 +1,328 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_charmm_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "pair.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +void DihedralCharmmOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + // insure pair->ev_tally() will use 1-4 virial contribution + + if (weightflag && vflag_global == 2) + force->pair->vflag_either = force->pair->vflag_global = 1; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + + // reduce contributions to non-bonded energy terms + for (int n = 0; n < nthreads; ++n) { + force->pair->eng_vdwl += eng_vdwl_thr[n]; + force->pair->eng_coul += eng_coul_thr[n]; + } +} + +template +void DihedralCharmmOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,i,m,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; + double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; + double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; + double c,s,p,sx2,sy2,sz2; + int itype,jtype; + double delx,dely,delz,rsq,r2inv,r6inv; + double forcecoul,forcelj,fpair,ecoul,evdwl; + + edihedral = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *atomtype = atom->type; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + double qqrd2e = force->qqrd2e; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c,s calculation + + ax = vb1y*vb2zm - vb1z*vb2ym; + ay = vb1z*vb2xm - vb1x*vb2zm; + az = vb1x*vb2ym - vb1y*vb2xm; + bx = vb3y*vb2zm - vb3z*vb2ym; + by = vb3z*vb2xm - vb3x*vb2zm; + bz = vb3x*vb2ym - vb3y*vb2xm; + + rasq = ax*ax + ay*ay + az*az; + rbsq = bx*bx + by*by + bz*bz; + rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; + rg = sqrt(rgsq); + + rginv = ra2inv = rb2inv = 0.0; + if (rg > 0) rginv = 1.0/rg; + if (rasq > 0) ra2inv = 1.0/rasq; + if (rbsq > 0) rb2inv = 1.0/rbsq; + rabinv = sqrt(ra2inv*rb2inv); + + c = (ax*bx + ay*by + az*bz)*rabinv; + s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + m = multiplicity[type]; + p = 1.0; + df1 = 0.0; + + for (i = 0; i < m; i++) { + ddf1 = p*c - df1*s; + df1 = p*s + df1*c; + p = ddf1; + } + + p = p*cos_shift[type] + df1*sin_shift[type]; + df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; + df1 *= -m; + p += 1.0; + + if (m == 0) { + p = 1.0 + cos_shift[type]; + df1 = 0.0; + } + + if (EFLAG) edihedral = k[type] * p; + + fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; + hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; + fga = fg*ra2inv*rginv; + hgb = hg*rb2inv*rginv; + gaa = -ra2inv*rg; + gbb = rb2inv*rg; + + dtfx = gaa*ax; + dtfy = gaa*ay; + dtfz = gaa*az; + dtgx = fga*ax - hgb*bx; + dtgy = fga*ay - hgb*by; + dtgz = fga*az - hgb*bz; + dthx = gbb*bx; + dthy = gbb*by; + dthz = gbb*bz; + + df = -k[type] * df1; + + sx2 = df*dtgx; + sy2 = df*dtgy; + sz2 = df*dtgz; + + f1[0] = df*dtfx; + f1[1] = df*dtfy; + f1[2] = df*dtfz; + + f2[0] = sx2 - f1[0]; + f2[1] = sy2 - f1[1]; + f2[2] = sz2 - f1[2]; + + f4[0] = df*dthx; + f4[1] = df*dthy; + f4[2] = df*dthz; + + f3[0] = -sx2 - f4[0]; + f3[1] = -sy2 - f4[1]; + f3[2] = -sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + // 1-4 LJ and Coulomb interactions + // tally energy/virial in pair, using newton_bond as newton flag + + if (weight[type] > 0.0) { + itype = atomtype[i1]; + jtype = atomtype[i4]; + + delx = x[i1][0] - x[i4][0]; + dely = x[i1][1] - x[i4][1]; + delz = x[i1][2] - x[i4][2]; + domain->minimum_image(delx,dely,delz); + rsq = delx*delx + dely*dely + delz*delz; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + + if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; + else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); + forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]); + fpair = weight[type] * (forcelj+forcecoul)*r2inv; + + if (EFLAG) { + ecoul = weight[type] * forcecoul; + evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]); + evdwl *= weight[type]; + } + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += delx*fpair; + f[i1][1] += dely*fpair; + f[i1][2] += delz*fpair; + } + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] -= delx*fpair; + f[i4][1] -= dely*fpair; + f[i4][2] -= delz*fpair; + } + + if (EVFLAG) ev_tally_thr(force->pair,i1,i4,nlocal,NEWTON_BOND, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } +} + diff --git a/src/USER-OMP/dihedral_charmm_omp.h b/src/USER-OMP/dihedral_charmm_omp.h new file mode 100644 index 0000000000..a39ad83f7e --- /dev/null +++ b/src/USER-OMP/dihedral_charmm_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(charmm/omp,DihedralCharmmOMP) + +#else + +#ifndef LMP_DIHEDRAL_CHARMM_OMP_H +#define LMP_DIHEDRAL_CHARMM_OMP_H + +#include "dihedral_charmm.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralCharmmOMP : public DihedralCharmm, public ThrOMP { + + public: + DihedralCharmmOMP(class LAMMPS *lmp) : + DihedralCharmm(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_class2_omp.cpp b/src/USER-OMP/dihedral_class2_omp.cpp new file mode 100644 index 0000000000..7348296644 --- /dev/null +++ b/src/USER-OMP/dihedral_class2_omp.cpp @@ -0,0 +1,532 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_class2_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.0000001 + +/* ---------------------------------------------------------------------- */ + +void DihedralClass2OMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralClass2OMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,i,j,k,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral; + double r1mag2,r1,r2mag2,r2,r3mag2,r3; + double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1; + double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c; + double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2; + double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3; + double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2; + double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0; + double r3_0,dr1,dr2,tk1,tk2,s12,sin2; + double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3]; + double fabcd[4][3]; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // distances + + r1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + r1 = sqrt(r1mag2); + r2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + r2 = sqrt(r2mag2); + r3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + r3 = sqrt(r3mag2); + + sb1 = 1.0/r1mag2; + rb1 = 1.0/r1; + sb2 = 1.0/r2mag2; + rb2 = 1.0/r2; + sb3 = 1.0/r3mag2; + rb3 = 1.0/r3; + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // angles + + r12c1 = rb1*rb2; + r12c2 = rb2*rb3; + costh12 = (vb1x*vb2x + vb1y*vb2y + vb1z*vb2z) * r12c1; + costh13 = c0; + costh23 = (vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z) * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - costh12*costh12,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - costh23*costh23,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + costh12*costh23) * s12; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me; + MPI_Comm_rank(world,&me); + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", + me,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + cosphi = c; + phi = acos(c); + + sinphi = sqrt(1.0 - c*c); + sinphi = MAX(sinphi,SMALL); + + a11 = -c*sb1*s1; + a22 = sb2 * (2.0*costh13*s12 - c*(s1+s2)); + a33 = -c*sb3*s2; + a12 = r12c1 * (costh12*c*s1 + costh23*s12); + a13 = rb1*rb3*s12; + a23 = r12c2 * (-costh23*c*s2 - costh12*s12); + + sx1 = a11*vb1x + a12*vb2x + a13*vb3x; + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sx12 = a13*vb1x + a23*vb2x + a33*vb3x; + sy1 = a11*vb1y + a12*vb2y + a13*vb3y; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sy12 = a13*vb1y + a23*vb2y + a33*vb3y; + sz1 = a11*vb1z + a12*vb2z + a13*vb3z; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + sz12 = a13*vb1z + a23*vb2z + a33*vb3z; + + // set up d(cos(phi))/d(r) and dphi/dr arrays + + dcosphidr[0][0] = -sx1; + dcosphidr[0][1] = -sy1; + dcosphidr[0][2] = -sz1; + dcosphidr[1][0] = sx2 + sx1; + dcosphidr[1][1] = sy2 + sy1; + dcosphidr[1][2] = sz2 + sz1; + dcosphidr[2][0] = sx12 - sx2; + dcosphidr[2][1] = sy12 - sy2; + dcosphidr[2][2] = sz12 - sz2; + dcosphidr[3][0] = -sx12; + dcosphidr[3][1] = -sy12; + dcosphidr[3][2] = -sz12; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + dphidr[i][j] = -dcosphidr[i][j] / sinphi; + + // energy + + dphi1 = phi - phi1[type]; + dphi2 = 2.0*phi - phi2[type]; + dphi3 = 3.0*phi - phi3[type]; + + if (EFLAG) edihedral = k1[type]*(1.0 - cos(dphi1)) + + k2[type]*(1.0 - cos(dphi2)) + + k3[type]*(1.0 - cos(dphi3)); + + de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) + + 3.0*k3[type]*sin(dphi3); + + // torsion forces on all 4 atoms + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] = de_dihedral*dphidr[i][j]; + + // set up d(bond)/d(r) array + // dbonddr(i,j,k) = bond i, atom j, coordinate k + + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + for (k = 0; k < 3; k++) + dbonddr[i][j][k] = 0.0; + + // bond1 + + dbonddr[0][0][0] = vb1x / r1; + dbonddr[0][0][1] = vb1y / r1; + dbonddr[0][0][2] = vb1z / r1; + dbonddr[0][1][0] = -vb1x / r1; + dbonddr[0][1][1] = -vb1y / r1; + dbonddr[0][1][2] = -vb1z / r1; + + // bond2 + + dbonddr[1][1][0] = vb2x / r2; + dbonddr[1][1][1] = vb2y / r2; + dbonddr[1][1][2] = vb2z / r2; + dbonddr[1][2][0] = -vb2x / r2; + dbonddr[1][2][1] = -vb2y / r2; + dbonddr[1][2][2] = -vb2z / r2; + + // bond3 + + dbonddr[2][2][0] = vb3x / r3; + dbonddr[2][2][1] = vb3y / r3; + dbonddr[2][2][2] = vb3z / r3; + dbonddr[2][3][0] = -vb3x / r3; + dbonddr[2][3][1] = -vb3y / r3; + dbonddr[2][3][2] = -vb3z / r3; + + // set up d(theta)/d(r) array + // dthetadr(i,j,k) = angle i, atom j, coordinate k + + for (i = 0; i < 2; i++) + for (j = 0; j < 4; j++) + for (k = 0; k < 3; k++) + dthetadr[i][j][k] = 0.0; + + t1 = costh12 / r1mag2; + t2 = costh23 / r2mag2; + t3 = costh12 / r2mag2; + t4 = costh23 / r3mag2; + + // angle12 + + dthetadr[0][0][0] = sc1 * ((t1 * vb1x) - (vb2x * r12c1)); + dthetadr[0][0][1] = sc1 * ((t1 * vb1y) - (vb2y * r12c1)); + dthetadr[0][0][2] = sc1 * ((t1 * vb1z) - (vb2z * r12c1)); + + dthetadr[0][1][0] = sc1 * ((-t1 * vb1x) + (vb2x * r12c1) + + (-t3 * vb2x) + (vb1x * r12c1)); + dthetadr[0][1][1] = sc1 * ((-t1 * vb1y) + (vb2y * r12c1) + + (-t3 * vb2y) + (vb1y * r12c1)); + dthetadr[0][1][2] = sc1 * ((-t1 * vb1z) + (vb2z * r12c1) + + (-t3 * vb2z) + (vb1z * r12c1)); + + dthetadr[0][2][0] = sc1 * ((t3 * vb2x) - (vb1x * r12c1)); + dthetadr[0][2][1] = sc1 * ((t3 * vb2y) - (vb1y * r12c1)); + dthetadr[0][2][2] = sc1 * ((t3 * vb2z) - (vb1z * r12c1)); + + // angle23 + + dthetadr[1][1][0] = sc2 * ((t2 * vb2x) + (vb3x * r12c2)); + dthetadr[1][1][1] = sc2 * ((t2 * vb2y) + (vb3y * r12c2)); + dthetadr[1][1][2] = sc2 * ((t2 * vb2z) + (vb3z * r12c2)); + + dthetadr[1][2][0] = sc2 * ((-t2 * vb2x) - (vb3x * r12c2) + + (t4 * vb3x) + (vb2x * r12c2)); + dthetadr[1][2][1] = sc2 * ((-t2 * vb2y) - (vb3y * r12c2) + + (t4 * vb3y) + (vb2y * r12c2)); + dthetadr[1][2][2] = sc2 * ((-t2 * vb2z) - (vb3z * r12c2) + + (t4 * vb3z) + (vb2z * r12c2)); + + dthetadr[1][3][0] = -sc2 * ((t4 * vb3x) + (vb2x * r12c2)); + dthetadr[1][3][1] = -sc2 * ((t4 * vb3y) + (vb2y * r12c2)); + dthetadr[1][3][2] = -sc2 * ((t4 * vb3z) + (vb2z * r12c2)); + + // mid-bond/torsion coupling + // energy on bond2 (middle bond) + + cos2phi = cos(2.0*phi); + cos3phi = cos(3.0*phi); + + bt1 = mbt_f1[type] * cosphi; + bt2 = mbt_f2[type] * cos2phi; + bt3 = mbt_f3[type] * cos3phi; + sumbte = bt1 + bt2 + bt3; + db = r2 - mbt_r0[type]; + if (EFLAG) edihedral += db * sumbte; + + // force on bond2 + + bt1 = -mbt_f1[type] * sinphi; + bt2 = -2.0 * mbt_f2[type] * sin(2.0*phi); + bt3 = -3.0 * mbt_f3[type] * sin(3.0*phi); + sumbtf = bt1 + bt2 + bt3; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[1][i][j]; + + // end-bond/torsion coupling + // energy on bond1 (first bond) + + bt1 = ebt_f1_1[type] * cosphi; + bt2 = ebt_f2_1[type] * cos2phi; + bt3 = ebt_f3_1[type] * cos3phi; + sumbte = bt1 + bt2 + bt3; + + db = r1 - ebt_r0_1[type]; + if (EFLAG) edihedral += db * (bt1+bt2+bt3); + + // force on bond1 + + bt1 = ebt_f1_1[type] * sinphi; + bt2 = 2.0 * ebt_f2_1[type] * sin(2.0*phi); + bt3 = 3.0 * ebt_f3_1[type] * sin(3.0*phi); + sumbtf = bt1 + bt2 + bt3; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] -= db*sumbtf*dphidr[i][j] + sumbte*dbonddr[0][i][j]; + + // end-bond/torsion coupling + // energy on bond3 (last bond) + + bt1 = ebt_f1_2[type] * cosphi; + bt2 = ebt_f2_2[type] * cos2phi; + bt3 = ebt_f3_2[type] * cos3phi; + sumbte = bt1 + bt2 + bt3; + + db = r3 - ebt_r0_2[type]; + if (EFLAG) edihedral += db * (bt1+bt2+bt3); + + // force on bond3 + + bt1 = -ebt_f1_2[type] * sinphi; + bt2 = -2.0 * ebt_f2_2[type] * sin(2.0*phi); + bt3 = -3.0 * ebt_f3_2[type] * sin(3.0*phi); + sumbtf = bt1 + bt2 + bt3; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[2][i][j]; + + // angle/torsion coupling + // energy on angle1 + + at1 = at_f1_1[type] * cosphi; + at2 = at_f2_1[type] * cos2phi; + at3 = at_f3_1[type] * cos3phi; + sumbte = at1 + at2 + at3; + + da = acos(costh12) - at_theta0_1[type]; + if (EFLAG) edihedral += da * (at1+at2+at3); + + // force on angle1 + + bt1 = at_f1_1[type] * sinphi; + bt2 = 2.0 * at_f2_1[type] * sin(2.0*phi); + bt3 = 3.0 * at_f3_1[type] * sin(3.0*phi); + sumbtf = bt1 + bt2 + bt3; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] -= da*sumbtf*dphidr[i][j] + sumbte*dthetadr[0][i][j]; + + // energy on angle2 + + at1 = at_f1_2[type] * cosphi; + at2 = at_f2_2[type] * cos2phi; + at3 = at_f3_2[type] * cos3phi; + sumbte = at1 + at2 + at3; + + da = acos(costh23) - at_theta0_2[type]; + if (EFLAG) edihedral += da * (at1+at2+at3); + + // force on angle2 + + bt1 = -at_f1_2[type] * sinphi; + bt2 = -2.0 * at_f2_2[type] * sin(2.0*phi); + bt3 = -3.0 * at_f3_2[type] * sin(3.0*phi); + sumbtf = bt1 + bt2 + bt3; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] += da*sumbtf*dphidr[i][j] + sumbte*dthetadr[1][i][j]; + + // angle/angle/torsion coupling + + da1 = acos(costh12) - aat_theta0_1[type]; + da2 = acos(costh23) - aat_theta0_2[type]; + + if (EFLAG) edihedral += aat_k[type]*da1*da2*cosphi; + + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + fabcd[i][j] -= aat_k[type] * + (cosphi * (da2*dthetadr[0][i][j] - da1*dthetadr[1][i][j]) + + sinphi * da1*da2*dphidr[i][j]); + + // bond1/bond3 coupling + + if (fabs(bb13t_k[type]) > SMALL) { + + r1_0 = bb13t_r10[type]; + r3_0 = bb13t_r30[type]; + dr1 = r1 - r1_0; + dr2 = r3 - r3_0; + tk1 = -bb13t_k[type] * dr1 / r3; + tk2 = -bb13t_k[type] * dr2 / r1; + + if (EFLAG) edihedral += bb13t_k[type]*dr1*dr2; + + fabcd[0][0] += tk2 * vb1x; + fabcd[0][1] += tk2 * vb1y; + fabcd[0][2] += tk2 * vb1z; + + fabcd[1][0] -= tk2 * vb1x; + fabcd[1][1] -= tk2 * vb1y; + fabcd[1][2] -= tk2 * vb1z; + + fabcd[2][0] -= tk1 * vb3x; + fabcd[2][1] -= tk1 * vb3y; + fabcd[2][2] -= tk1 * vb3z; + + fabcd[3][0] += tk1 * vb3x; + fabcd[3][1] += tk1 * vb3y; + fabcd[3][2] += tk1 * vb3z; + } + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += fabcd[0][0]; + f[i1][1] += fabcd[0][1]; + f[i1][2] += fabcd[0][2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += fabcd[1][0]; + f[i2][1] += fabcd[1][1]; + f[i2][2] += fabcd[1][2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += fabcd[2][0]; + f[i3][1] += fabcd[2][1]; + f[i3][2] += fabcd[2][2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += fabcd[3][0]; + f[i4][1] += fabcd[3][1]; + f[i4][2] += fabcd[3][2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral, + fabcd[0],fabcd[2],fabcd[3], + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} + diff --git a/src/USER-OMP/dihedral_class2_omp.h b/src/USER-OMP/dihedral_class2_omp.h new file mode 100644 index 0000000000..d26f2f8713 --- /dev/null +++ b/src/USER-OMP/dihedral_class2_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(class2/omp,DihedralClass2OMP) + +#else + +#ifndef LMP_DIHEDRAL_CLASS2_OMP_H +#define LMP_DIHEDRAL_CLASS2_OMP_H + +#include "dihedral_class2.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralClass2OMP : public DihedralClass2, public ThrOMP { + + public: + DihedralClass2OMP(class LAMMPS *lmp) : + DihedralClass2(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp new file mode 100644 index 0000000000..a6c027e92d --- /dev/null +++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp @@ -0,0 +1,263 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_cosine_shift_exp_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +void DihedralCosineShiftExpOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralCosineShiftExpOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; + double df,fg,hg,fga,hgb,gaa,gbb; + double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; + double c,s,sx2,sy2,sz2; + double cccpsss,cssmscc,exp2; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c,s calculation + + ax = vb1y*vb2zm - vb1z*vb2ym; + ay = vb1z*vb2xm - vb1x*vb2zm; + az = vb1x*vb2ym - vb1y*vb2xm; + bx = vb3y*vb2zm - vb3z*vb2ym; + by = vb3z*vb2xm - vb3x*vb2zm; + bz = vb3x*vb2ym - vb3y*vb2xm; + + rasq = ax*ax + ay*ay + az*az; + rbsq = bx*bx + by*by + bz*bz; + rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; + rg = sqrt(rgsq); + + rginv = ra2inv = rb2inv = 0.0; + if (rg > 0) rginv = 1.0/rg; + if (rasq > 0) ra2inv = 1.0/rasq; + if (rbsq > 0) rb2inv = 1.0/rbsq; + rabinv = sqrt(ra2inv*rb2inv); + + c = (ax*bx + ay*by + az*bz)*rabinv; + s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + double aa=a[type]; + double uumin=umin[type]; + + cccpsss = c*cost[type]+s*sint[type]; + cssmscc = c*sint[type]-s*cost[type]; + + if (doExpansion[type]) { + // |a|<0.001 so use expansions relative precision <1e-5 + if (EFLAG) edihedral = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin; + df=0.5*uumin*( cssmscc + 0.5*aa*cccpsss); + } else { + exp2=exp(0.5*aa*(1+cccpsss)); + if (EFLAG) edihedral = opt1[type]*(1-exp2); + df= 0.5*opt1[type]*aa* ( exp2*cssmscc ); + } + + fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; + hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; + fga = fg*ra2inv*rginv; + hgb = hg*rb2inv*rginv; + gaa = -ra2inv*rg; + gbb = rb2inv*rg; + + dtfx = gaa*ax; + dtfy = gaa*ay; + dtfz = gaa*az; + dtgx = fga*ax - hgb*bx; + dtgy = fga*ay - hgb*by; + dtgz = fga*az - hgb*bz; + dthx = gbb*bx; + dthy = gbb*by; + dthz = gbb*bz; + + sx2 = df*dtgx; + sy2 = df*dtgy; + sz2 = df*dtgz; + + f1[0] = df*dtfx; + f1[1] = df*dtfy; + f1[2] = df*dtfz; + + f2[0] = sx2 - f1[0]; + f2[1] = sy2 - f1[1]; + f2[2] = sz2 - f1[2]; + + f4[0] = df*dthx; + f4[1] = df*dthy; + f4[2] = df*dthz; + + f3[0] = -sx2 - f4[0]; + f3[1] = -sy2 - f4[1]; + f3[2] = -sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} + diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.h b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h new file mode 100644 index 0000000000..eb906ab953 --- /dev/null +++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(cosine/shift/exp/omp,DihedralCosineShiftExpOMP) + +#else + +#ifndef LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H +#define LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H + +#include "dihedral_cosine_shift_exp.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralCosineShiftExpOMP : public DihedralCosineShiftExp, public ThrOMP { + + public: + DihedralCosineShiftExpOMP(class LAMMPS *lmp) : + DihedralCosineShiftExp(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_harmonic_omp.cpp b/src/USER-OMP/dihedral_harmonic_omp.cpp new file mode 100644 index 0000000000..0fa24090a7 --- /dev/null +++ b/src/USER-OMP/dihedral_harmonic_omp.cpp @@ -0,0 +1,270 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_harmonic_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +void DihedralHarmonicOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralHarmonicOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,i,m,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; + double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; + double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; + double c,s,p,sx2,sy2,sz2; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c,s calculation + + ax = vb1y*vb2zm - vb1z*vb2ym; + ay = vb1z*vb2xm - vb1x*vb2zm; + az = vb1x*vb2ym - vb1y*vb2xm; + bx = vb3y*vb2zm - vb3z*vb2ym; + by = vb3z*vb2xm - vb3x*vb2zm; + bz = vb3x*vb2ym - vb3y*vb2xm; + + rasq = ax*ax + ay*ay + az*az; + rbsq = bx*bx + by*by + bz*bz; + rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; + rg = sqrt(rgsq); + + rginv = ra2inv = rb2inv = 0.0; + if (rg > 0) rginv = 1.0/rg; + if (rasq > 0) ra2inv = 1.0/rasq; + if (rbsq > 0) rb2inv = 1.0/rbsq; + rabinv = sqrt(ra2inv*rb2inv); + + c = (ax*bx + ay*by + az*bz)*rabinv; + s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + m = multiplicity[type]; + p = 1.0; + df1 = 0.0; + + for (i = 0; i < m; i++) { + ddf1 = p*c - df1*s; + df1 = p*s + df1*c; + p = ddf1; + } + + p = p*cos_shift[type] + df1*sin_shift[type]; + df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; + df1 *= -m; + p += 1.0; + + if (m == 0) { + p = 1.0 + cos_shift[type]; + df1 = 0.0; + } + + if (EFLAG) edihedral = k[type] * p; + + fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; + hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; + fga = fg*ra2inv*rginv; + hgb = hg*rb2inv*rginv; + gaa = -ra2inv*rg; + gbb = rb2inv*rg; + + dtfx = gaa*ax; + dtfy = gaa*ay; + dtfz = gaa*az; + dtgx = fga*ax - hgb*bx; + dtgy = fga*ay - hgb*by; + dtgz = fga*az - hgb*bz; + dthx = gbb*bx; + dthy = gbb*by; + dthz = gbb*bz; + + df = -k[type] * df1; + + sx2 = df*dtgx; + sy2 = df*dtgy; + sz2 = df*dtgz; + + f1[0] = df*dtfx; + f1[1] = df*dtfy; + f1[2] = df*dtfz; + + f2[0] = sx2 - f1[0]; + f2[1] = sy2 - f1[1]; + f2[2] = sz2 - f1[2]; + + f4[0] = df*dthx; + f4[1] = df*dthy; + f4[2] = df*dthz; + + f3[0] = -sx2 - f4[0]; + f3[1] = -sy2 - f4[1]; + f3[2] = -sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} + diff --git a/src/USER-OMP/dihedral_harmonic_omp.h b/src/USER-OMP/dihedral_harmonic_omp.h new file mode 100644 index 0000000000..2d7bae64ee --- /dev/null +++ b/src/USER-OMP/dihedral_harmonic_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(harmonic/omp,DihedralHarmonicOMP) + +#else + +#ifndef LMP_DIHEDRAL_HARMONIC_OMP_H +#define LMP_DIHEDRAL_HARMONIC_OMP_H + +#include "dihedral_harmonic.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralHarmonicOMP : public DihedralHarmonic, public ThrOMP { + + public: + DihedralHarmonicOMP(class LAMMPS *lmp) : + DihedralHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp new file mode 100644 index 0000000000..a3ca969ef3 --- /dev/null +++ b/src/USER-OMP/dihedral_helix_omp.cpp @@ -0,0 +1,280 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_helix_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 +#define SMALLER 0.00001 + +/* ---------------------------------------------------------------------- */ + +void DihedralHelixOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralHelixOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; + double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; + double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22; + double a33,a12,a13,a23,sx2,sy2,sz2; + double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c0 calculation + + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + cx = vb1y*vb2z - vb1z*vb2y; + cy = vb1z*vb2x - vb1x*vb2z; + cz = vb1x*vb2y - vb1y*vb2x; + cmag = sqrt(cx*cx + cy*cy + cz*cz); + dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + phi = acos(c); + if (dx < 0.0) phi *= -1.0; + si = sin(phi); + if (fabs(si) < SMALLER) si = SMALLER; + siinv = 1.0/si; + + pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + + cphi[type]*sin(phi + 0.25*PI)*siinv; + + if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + + cphi[type]*(1.0 + cos(phi + 0.25*PI)); +; + + a = pd; + c = c * a; + s12 = s12 * a; + a11 = c*sb1*s1; + a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + a33 = c*sb3*s2; + a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); + a13 = -rb1*rb3*s12; + a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); + + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} diff --git a/src/USER-OMP/dihedral_helix_omp.h b/src/USER-OMP/dihedral_helix_omp.h new file mode 100644 index 0000000000..7923197413 --- /dev/null +++ b/src/USER-OMP/dihedral_helix_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(helix/omp,DihedralHelixOMP) + +#else + +#ifndef LMP_DIHEDRAL_HELIX_OMP_H +#define LMP_DIHEDRAL_HELIX_OMP_H + +#include "dihedral_helix.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralHelixOMP : public DihedralHelix, public ThrOMP { + + public: + DihedralHelixOMP(class LAMMPS *lmp) : + DihedralHelix(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp new file mode 100644 index 0000000000..bde958984e --- /dev/null +++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp @@ -0,0 +1,269 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_multi_harmonic_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +void DihedralMultiHarmonicOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralMultiHarmonicOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; + double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; + double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22; + double a33,a12,a13,a23,sx2,sy2,sz2; + double s2,sin2; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c0 calculation + + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + // force & energy + // p = sum (i=1,5) a_i * c**(i-1) + // pd = dp/dc + + pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type])); + + if (EFLAG) + edihedral = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type]))); + + a = pd; + c = c * a; + s12 = s12 * a; + a11 = c*sb1*s1; + a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + a33 = c*sb3*s2; + a12 = -r12c1*(c1mag*c*s1 + c2mag*s12); + a13 = -rb1*rb3*s12; + a23 = r12c2*(c2mag*c*s2 + c1mag*s12); + + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.h b/src/USER-OMP/dihedral_multi_harmonic_omp.h new file mode 100644 index 0000000000..da2322f038 --- /dev/null +++ b/src/USER-OMP/dihedral_multi_harmonic_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(multi/harmonic/omp,DihedralMultiHarmonicOMP) + +#else + +#ifndef LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H +#define LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H + +#include "dihedral_multi_harmonic.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralMultiHarmonicOMP : public DihedralMultiHarmonic, public ThrOMP { + + public: + DihedralMultiHarmonicOMP(class LAMMPS *lmp) : + DihedralMultiHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/dihedral_opls_omp.cpp b/src/USER-OMP/dihedral_opls_omp.cpp new file mode 100644 index 0000000000..9f59e26d26 --- /dev/null +++ b/src/USER-OMP/dihedral_opls_omp.cpp @@ -0,0 +1,286 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include "math.h" +#include "dihedral_opls_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 +#define SMALLER 0.00001 + +/* ---------------------------------------------------------------------- */ + +void DihedralOPLSOMP::compute(int eflag, int vflag) +{ + + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = neighbor->ndihedrallist; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void DihedralOPLSOMP::eval(double **f, int nfrom, int nto, int tid) +{ + + int i1,i2,i3,i4,n,type; + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double edihedral,f1[3],f2[3],f3[3],f4[3]; + double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; + double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; + double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22; + double a33,a12,a13,a23,sx2,sy2,sz2; + double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; + + edihedral = 0.0; + + double **x = atom->x; + int **dihedrallist = neighbor->dihedrallist; + int nlocal = atom->nlocal; + + for (n = nfrom; n < nto; n++) { + i1 = dihedrallist[n][0]; + i2 = dihedrallist[n][1]; + i3 = dihedrallist[n][2]; + i4 = dihedrallist[n][3]; + type = dihedrallist[n][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + domain->minimum_image(vb1x,vb1y,vb1z); + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + domain->minimum_image(vb2x,vb2y,vb2z); + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + domain->minimum_image(vb2xm,vb2ym,vb2zm); + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + domain->minimum_image(vb3x,vb3y,vb3z); + + // c0 calculation + + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + cx = vb1y*vb2z - vb1z*vb2y; + cy = vb1z*vb2x - vb1x*vb2z; + cz = vb1x*vb2y - vb1y*vb2x; + cmag = sqrt(cx*cx + cy*cy + cz*cz); + dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { + int me = comm->me; + + if (screen) { + char str[128]; + sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", + me,tid,update->ntimestep, + atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); + error->warning(FLERR,str,0); + fprintf(screen," 1st atom: %d %g %g %g\n", + me,x[i1][0],x[i1][1],x[i1][2]); + fprintf(screen," 2nd atom: %d %g %g %g\n", + me,x[i2][0],x[i2][1],x[i2][2]); + fprintf(screen," 3rd atom: %d %g %g %g\n", + me,x[i3][0],x[i3][1],x[i3][2]); + fprintf(screen," 4th atom: %d %g %g %g\n", + me,x[i4][0],x[i4][1],x[i4][2]); + } + } + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + // force & energy + // p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) ) + // pd = dp/dc + + phi = acos(c); + if (dx < 0.0) phi *= -1.0; + si = sin(phi); + if (fabs(si) < SMALLER) si = SMALLER; + siinv = 1.0/si; + + pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv + + 3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv; + + if (EFLAG) edihedral = k1[type]*(1.0 + c) + k2[type]*(1.0 - cos(2.0*phi)) + + k3[type]*(1.0 + cos(3.0*phi)) + k4[type]*(1.0 - cos(4.0*phi)); + + + a = pd; + c = c * a; + s12 = s12 * a; + a11 = c*sb1*s1; + a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + a33 = c*sb3*s2; + a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); + a13 = -rb1*rb3*s12; + a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); + + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // apply force to each of 4 atoms + + if (NEWTON_BOND || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (NEWTON_BOND || i2 < nlocal) { + f[i2][0] += f2[0]; + f[i2][1] += f2[1]; + f[i2][2] += f2[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (NEWTON_BOND || i4 < nlocal) { + f[i4][0] += f4[0]; + f[i4][1] += f4[1]; + f[i4][2] += f4[2]; + } + + if (EVFLAG) + ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid); + } +} + diff --git a/src/USER-OMP/dihedral_opls_omp.h b/src/USER-OMP/dihedral_opls_omp.h new file mode 100644 index 0000000000..58b9920538 --- /dev/null +++ b/src/USER-OMP/dihedral_opls_omp.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef DIHEDRAL_CLASS + +DihedralStyle(opls/omp,DihedralOPLSOMP) + +#else + +#ifndef LMP_DIHEDRAL_OPLS_OMP_H +#define LMP_DIHEDRAL_OPLS_OMP_H + +#include "dihedral_opls.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class DihedralOPLSOMP : public DihedralOPLS, public ThrOMP { + + public: + DihedralOPLSOMP(class LAMMPS *lmp) : + DihedralOPLS(lmp), ThrOMP(lmp,DIHEDRAL) {}; + + virtual void compute(int, int); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/fix_gravity_omp.cpp b/src/USER-OMP/fix_gravity_omp.cpp new file mode 100644 index 0000000000..c4f4b39b6c --- /dev/null +++ b/src/USER-OMP/fix_gravity_omp.cpp @@ -0,0 +1,114 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "fix_gravity_omp.h" +#include "atom.h" +#include "update.h" +#include "domain.h" +#include "respa.h" +#include "error.h" + +using namespace LAMMPS_NS; + +enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; + +/* ---------------------------------------------------------------------- */ + +FixGravityOMP::FixGravityOMP(LAMMPS *lmp, int narg, char **arg) : + FixGravity(lmp, narg, arg) { } + +/* ---------------------------------------------------------------------- */ + +void FixGravityOMP::post_force(int vflag) +{ + // update direction of gravity vector if gradient style + + if (style == GRADIENT) { + if (domain->dimension == 3) { + double phi_current = degree2rad * + (phi + (update->ntimestep - time_origin)*dt*phigrad*360.0); + double theta_current = degree2rad * + (theta + (update->ntimestep - time_origin)*dt*thetagrad*360.0); + xgrav = sin(theta_current) * cos(phi_current); + ygrav = sin(theta_current) * sin(phi_current); + zgrav = cos(theta_current); + } else { + double theta_current = degree2rad * + (theta + (update->ntimestep - time_origin)*dt*thetagrad*360.0); + xgrav = sin(theta_current); + ygrav = cos(theta_current); + } + xacc = magnitude*xgrav; + yacc = magnitude*ygrav; + zacc = magnitude*zgrav; + } + + const double * const * const x = atom->x; + double * const * const f = atom->f; + double * const rmass = atom->rmass; + double * const mass = atom->mass; + int * const mask = atom->mask; + int * const type = atom->type; + const int nlocal = atom->nlocal; + const double xacc_thr = xacc; + const double yacc_thr = yacc; + const double zacc_thr = zacc; + double massone; + + int i; + eflag = 0; + double grav = 0.0; + + if (rmass) { +#if defined(_OPENMP) +#pragma omp parallel for private(i,massone) default(none) reduction(-:grav) +#endif + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + massone = rmass[i]; + f[i][0] += massone*xacc_thr; + f[i][1] += massone*yacc_thr; + f[i][2] += massone*zacc_thr; + grav -= massone * (xacc_thr*x[i][0] + yacc_thr*x[i][1] + zacc_thr*x[i][2]); + } + } else { +#if defined(_OPENMP) +#pragma omp parallel for private(i,massone) default(none) reduction(-:grav) +#endif + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + massone = mass[type[i]]; + f[i][0] += massone*xacc_thr; + f[i][1] += massone*yacc_thr; + f[i][2] += massone*zacc_thr; + grav -= massone * (xacc_thr*x[i][0] + yacc_thr*x[i][1] + zacc_thr*x[i][2]); + } + } + egrav = grav; +} + +/* ---------------------------------------------------------------------- */ + +void FixGravityOMP::post_force_respa(int vflag, int ilevel, int iloop) +{ + if (ilevel == nlevels_respa-1) post_force(vflag); +} + diff --git a/src/USER-OMP/fix_gravity_omp.h b/src/USER-OMP/fix_gravity_omp.h new file mode 100644 index 0000000000..dd0144410e --- /dev/null +++ b/src/USER-OMP/fix_gravity_omp.h @@ -0,0 +1,38 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(gravity/omp,FixGravityOMP) + +#else + +#ifndef LMP_FIX_GRAVITY_OMP_H +#define LMP_FIX_GRAVITY_OMP_H + +#include "fix_gravity.h" + +namespace LAMMPS_NS { + +class FixGravityOMP : public FixGravity { + + public: + FixGravityOMP(class LAMMPS *, int, char **); + virtual void post_force(int); + virtual void post_force_respa(int, int, int); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/fix_nve_sphere_omp.cpp b/src/USER-OMP/fix_nve_sphere_omp.cpp new file mode 100644 index 0000000000..a642b21f22 --- /dev/null +++ b/src/USER-OMP/fix_nve_sphere_omp.cpp @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "fix_nve_sphere_omp.h" +#include "atom.h" +#include "atom_vec.h" +#include "update.h" +#include "respa.h" +#include "force.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define INERTIA 0.4 // moment of inertia prefactor for sphere + +enum{NONE,DIPOLE}; + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- */ + +void FixNVESphereOMP::initial_integrate(int vflag) +{ + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *radius = atom->radius; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int i; + + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + const double dtfrotate = dtf / INERTIA; + + // update v,x,omega for all particles + // d_omega/dt = torque / inertia +#if defined(_OPENMP) +#pragma omp parallel for private(i) default(shared) +#endif + for (i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + const double dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + x[i][2] += dtv * v[i][2]; + + const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]); + omega[i][0] += dtirotate * torque[i][0]; + omega[i][1] += dtirotate * torque[i][1]; + omega[i][2] += dtirotate * torque[i][2]; + } + } + + // update mu for dipoles + // d_mu/dt = omega cross mu + // renormalize mu to dipole length + + if (extra == DIPOLE) { + double **mu = atom->mu; +#if defined(_OPENMP) +#pragma omp parallel for private(i) default(shared) +#endif + for (i = 0; i < nlocal; i++) { + double g0,g1,g2,msq,scale; + if (mask[i] & groupbit) { + if (mu[i][3] > 0.0) { + g0 = mu[i][0] + dtv * (omega[i][1]*mu[i][2]-omega[i][2]*mu[i][1]); + g1 = mu[i][1] + dtv * (omega[i][2]*mu[i][0]-omega[i][0]*mu[i][2]); + g2 = mu[i][2] + dtv * (omega[i][0]*mu[i][1]-omega[i][1]*mu[i][0]); + msq = g0*g0 + g1*g1 + g2*g2; + scale = mu[i][3]/sqrt(msq); + mu[i][0] = g0*scale; + mu[i][1] = g1*scale; + mu[i][2] = g2*scale; + } + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVESphereOMP::final_integrate() +{ + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + double *radius = atom->radius; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int i; + + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + const double dtfrotate = dtf / INERTIA; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + +#if defined(_OPENMP) +#pragma omp parallel for private(i) default(shared) +#endif + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + const double dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + + const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]); + omega[i][0] += dtirotate * torque[i][0]; + omega[i][1] += dtirotate * torque[i][1]; + omega[i][2] += dtirotate * torque[i][2]; + } +} diff --git a/src/USER-OMP/fix_nve_sphere_omp.h b/src/USER-OMP/fix_nve_sphere_omp.h new file mode 100644 index 0000000000..fe86039b18 --- /dev/null +++ b/src/USER-OMP/fix_nve_sphere_omp.h @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(nve/sphere/omp,FixNVESphereOMP) + +#else + +#ifndef LMP_FIX_NVE_SPHERE_OMP_H +#define LMP_FIX_NVE_SPHERE_OMP_H + +#include "fix_nve_sphere.h" + +namespace LAMMPS_NS { + +class FixNVESphereOMP : public FixNVESphere { + public: + FixNVESphereOMP(class LAMMPS *lmp, int narg, char **arg) : + FixNVESphere(lmp, narg, arg) {}; + + virtual void initial_integrate(int); + virtual void final_integrate(); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/fix_qeq_comb_omp.cpp b/src/USER-OMP/fix_qeq_comb_omp.cpp new file mode 100644 index 0000000000..175bab8986 --- /dev/null +++ b/src/USER-OMP/fix_qeq_comb_omp.cpp @@ -0,0 +1,166 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "lmptype.h" +#include "mpi.h" +#include +#include "fix_qeq_comb_omp.h" +#include "atom.h" +#include "force.h" +#include "group.h" +#include "memory.h" +#include "error.h" +#include "respa.h" +#include "update.h" +#include "pair_comb_omp.h" + +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixQEQCombOMP::FixQEQCombOMP(LAMMPS *lmp, int narg, char **arg) + : FixQEQComb(lmp, narg, arg) +{ + if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb/omp command"); +} + +/* ---------------------------------------------------------------------- */ + +void FixQEQCombOMP::init() +{ + if (!atom->q_flag) + error->all(FLERR,"Fix qeq/comb/omp requires atom attribute q"); + + comb = (PairComb *) force->pair_match("comb/omp",1); + if (comb == NULL) + comb = (PairComb *) force->pair_match("comb",1); + if (comb == NULL) error->all(FLERR,"Must use pair_style comb or comb/omp with fix qeq/comb"); + + if (strstr(update->integrate_style,"respa")) + nlevels_respa = ((Respa *) update->integrate)->nlevels; + + ngroup = group->count(igroup); + if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms"); +} + +/* ---------------------------------------------------------------------- */ + +void FixQEQCombOMP::post_force(int vflag) +{ + int i,iloop,loopmax; + double heatpq,qmass,dtq,dtq2; + double enegchkall,enegmaxall; + + if (update->ntimestep % nevery) return; + + // reallocate work arrays if necessary + // qf = charge force + // q1 = charge displacement + // q2 = tmp storage of charge force for next iteration + + if (atom->nmax > nmax) { + memory->destroy(qf); + memory->destroy(q1); + memory->destroy(q2); + nmax = atom->nmax; + memory->create(qf,nmax,"qeq:qf"); + memory->create(q1,nmax,"qeq:q1"); + memory->create(q2,nmax,"qeq:q2"); + vector_atom = qf; + } + + // more loops for first-time charge equilibrium + + iloop = 0; + if (firstflag) loopmax = 5000; + else loopmax = 2000; + + // charge-equilibration loop + + if (me == 0 && fp) + fprintf(fp,"Charge equilibration on step " BIGINT_FORMAT "\n", + update->ntimestep); + + heatpq = 0.05; + qmass = 0.000548580; + dtq = 0.0006; + dtq2 = 0.5*dtq*dtq/qmass; + + double enegchk = 0.0; + double enegtot = 0.0; + double enegmax = 0.0; + + double *q = atom->q; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + q1[i] = q2[i] = qf[i] = 0.0; + + for (iloop = 0; iloop < loopmax; iloop ++ ) { + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + q1[i] += qf[i]*dtq2 - heatpq*q1[i]; + q[i] += q1[i]; + } + + enegtot = comb->yasu_char(qf,igroup); + enegtot /= ngroup; + enegchk = enegmax = 0.0; + +#if defined(_OPENMP) +#pragma omp parallel for private(i) default(shared) +#endif + for (i = 0; i < nlocal ; i++) + if (mask[i] & groupbit) { + q2[i] = enegtot-qf[i]; + enegmax = MAX(enegmax,fabs(q2[i])); + enegchk += fabs(q2[i]); + qf[i] = q2[i]; + } + + MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world); + enegchk = enegchkall/ngroup; + MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world); + enegmax = enegmaxall; + + if (enegchk <= precision && enegmax <= 100.0*precision) break; + + if (me == 0 && fp) + fprintf(fp," iteration: %d, enegtot %.6g, " + "enegmax %.6g, fq deviation: %.6g\n", + iloop,enegtot,enegmax,enegchk); + +#if defined(_OPENMP) +#pragma omp parallel for private(i) default(shared) +#endif + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + q1[i] += qf[i]*dtq2 - heatpq*q1[i]; + } + + if (me == 0 && fp) { + if (iloop == loopmax) + fprintf(fp,"Charges did not converge in %d iterations\n",iloop); + else + fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n", + iloop,enegchk); + } +} + diff --git a/src/USER-OMP/fix_qeq_comb_omp.h b/src/USER-OMP/fix_qeq_comb_omp.h new file mode 100644 index 0000000000..0febe6b0aa --- /dev/null +++ b/src/USER-OMP/fix_qeq_comb_omp.h @@ -0,0 +1,32 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(qeq/comb/omp,FixQEQCombOMP) + +#else + +#ifndef LMP_FIX_QEQ_COMB_OMP_H +#define LMP_FIX_QEQ_COMB_OMP_H + +#include "fix_qeq_comb.h" + +namespace LAMMPS_NS { + +class FixQEQCombOMP : public FixQEQComb { + public: + FixQEQCombOMP(class LAMMPS *, int, char **); + virtual void init(); + virtual void post_force(int); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/fix_shear_history_omp.cpp b/src/USER-OMP/fix_shear_history_omp.cpp new file mode 100644 index 0000000000..40781cb407 --- /dev/null +++ b/src/USER-OMP/fix_shear_history_omp.cpp @@ -0,0 +1,150 @@ +/* ---------------------------------------------------------------------- + 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 "stdio.h" +#include "fix_shear_history_omp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "force.h" +#include "pair.h" +#include "update.h" +#include "modify.h" +#include "error.h" + +#if defined(_OPENMP) +#include +#endif + +using namespace LAMMPS_NS; + +#define MAXTOUCH 15 + +/* ---------------------------------------------------------------------- + copy shear partner info from neighbor lists to atom arrays + so can be exchanged with atoms +------------------------------------------------------------------------- */ + +void FixShearHistoryOMP::pre_exchange() +{ + + const int nlocal = atom->nlocal; + const int nghost = atom->nghost; + const int nall = nlocal + nghost; + const int nthreads = comm->nthreads; + + int flag = 0; +#if defined(_OPENMP) +#pragma omp parallel shared(flag) +#endif + { + +#if defined(_OPENMP) + const int tid = omp_get_thread_num(); +#else + const int tid = 0; +#endif + + // each thread works on a fixed chunk of local and ghost atoms. + const int ldelta = 1 + nlocal/nthreads; + const int lfrom = tid*ldelta; + const int lmax = lfrom +ldelta; + const int lto = (lmax > nlocal) ? nlocal : lmax; + + const int gdelta = 1 + nghost/nthreads; + const int gfrom = nlocal + tid*gdelta; + const int gmax = gfrom + gdelta; + const int gto = (gmax > nall) ? nall : gmax; + + + 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 + + for (i = lfrom; i < lto; i++) npartner[i] = 0; + + // copy shear info from neighbor list atoms to atom arrays + + int *tag = atom->tag; + + 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]) { + j = jlist[jj]; + j &= NEIGHMASK; + shear = &allshear[3*jj]; + + if ((i >= lfrom) && (i < lto)) { + if (npartner[i] < MAXTOUCH) { + m = npartner[i]; + partner[i][m] = tag[j]; + shearpartner[i][m][0] = shear[0]; + shearpartner[i][m][1] = shear[1]; + shearpartner[i][m][2] = shear[2]; + } + npartner[i]++; + } + + if ((j >= lfrom) && (j < lto)) { + if (npartner[j] < MAXTOUCH) { + m = npartner[j]; + partner[j][m] = tag[i]; + shearpartner[j][m][0] = -shear[0]; + shearpartner[j][m][1] = -shear[1]; + shearpartner[j][m][2] = -shear[2]; + } + npartner[j]++; + } + + if ((j >= gfrom) && (j < gto)) { + npartner[j]++; + } + } + } + } + + // test for too many touching neighbors + int myflag = 0; + for (i = lfrom; i < lto; i++) + if (npartner[i] >= MAXTOUCH) myflag = 1; + + if (myflag) +#if defined(_OPENMP) +#pragma omp atomic +#endif + ++flag; + } + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) error->all(FLERR,"Too many touching neighbors - boost MAXTOUCH"); +} diff --git a/src/USER-OMP/fix_shear_history_omp.h b/src/USER-OMP/fix_shear_history_omp.h new file mode 100644 index 0000000000..9a360b7923 --- /dev/null +++ b/src/USER-OMP/fix_shear_history_omp.h @@ -0,0 +1,38 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(SHEAR_HISTORY/omp,FixShearHistoryOMP) + +#else + +#ifndef LMP_FIX_SHEAR_HISTORY_OMP_H +#define LMP_FIX_SHEAR_HISTORY_OMP_H + +#include "fix_shear_history.h" + +namespace LAMMPS_NS { + +class FixShearHistoryOMP : public FixShearHistory { + + public: + FixShearHistoryOMP(class LAMMPS *lmp, int narg, char **argv) + : FixShearHistory(lmp,narg,argv) {}; + virtual void pre_exchange(); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_adp_omp.cpp b/src/USER-OMP/pair_adp_omp.cpp new file mode 100644 index 0000000000..e91642e6ba --- /dev/null +++ b/src/USER-OMP/pair_adp_omp.cpp @@ -0,0 +1,404 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" + +#include "pair_adp_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairADPOMP::PairADPOMP(LAMMPS *lmp) : + PairADP(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairADPOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow energy and fp arrays if necessary + // need to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(rho); + memory->destroy(fp); + memory->destroy(mu); + memory->destroy(lambda); + nmax = atom->nmax; + memory->create(rho,nthreads*nmax,"pair:rho"); + memory->create(fp,nmax,"pair:fp"); + memory->create(mu,nthreads*nmax,3,"pair:mu"); + memory->create(lambda,nthreads*nmax,6,"pair:lambda"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, *rho_t, **mu_t, **lambda_t; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + if (force->newton_pair) { + rho_t = rho + tid*nall; + mu_t = mu + tid*nall; + lambda_t = lambda + tid*nall; + } else { + rho_t = rho + tid*atom->nlocal; + mu_t = mu + tid*atom->nlocal; + lambda_t = lambda + tid*atom->nlocal; + } + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + else eval<1,1,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + else eval<1,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + else eval<0,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairADPOMP::eval(double **f, double *rho_t, double **mu_t, + double **lambda_t, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,m,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi; + double u2,u2p,w2,w2p,nu; + double *coeff; + int *ilist,*jlist,*numneigh,**firstneigh; + double delmux,delmuy,delmuz,trdelmu,tradellam; + double adpx,adpy,adpz,fx,fy,fz; + double sumlamxx,sumlamyy,sumlamzz,sumlamyz,sumlamxz,sumlamxy; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // zero out density + + if (NEWTON_PAIR) { + memset(rho_t, 0, nall*sizeof(double)); + memset(&(mu_t[0][0]), 0, 3*nall*sizeof(double)); + memset(&(lambda_t[0][0]), 0, 6*nall*sizeof(double)); + } else { + memset(rho_t, 0, nlocal*sizeof(double)); + memset(&(mu_t[0][0]), 0, 3*nlocal*sizeof(double)); + memset(&(lambda_t[0][0]), 0, 6*nlocal*sizeof(double)); + } + + // rho = density at each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + 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]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + jtype = type[j]; + p = sqrt(rsq)*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + coeff = rhor_spline[type2rhor[jtype][itype]][m]; + rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coeff = u2r_spline[type2u2r[jtype][itype]][m]; + u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + mu_t[i][0] += u2*delx; + mu_t[i][1] += u2*dely; + mu_t[i][2] += u2*delz; + coeff = w2r_spline[type2w2r[jtype][itype]][m]; + w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + lambda_t[i][0] += w2*delx*delx; + lambda_t[i][1] += w2*dely*dely; + lambda_t[i][2] += w2*delz*delz; + lambda_t[i][3] += w2*dely*delz; + lambda_t[i][4] += w2*delx*delz; + lambda_t[i][5] += w2*delx*dely; + + if (NEWTON_PAIR || j < nlocal) { + // verify sign difference for mu and lambda + coeff = rhor_spline[type2rhor[itype][jtype]][m]; + rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coeff = u2r_spline[type2u2r[itype][jtype]][m]; + u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + mu_t[j][0] -= u2*delx; + mu_t[j][1] -= u2*dely; + mu_t[j][2] -= u2*delz; + coeff = w2r_spline[type2w2r[itype][jtype]][m]; + w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + lambda_t[j][0] += w2*delx*delx; + lambda_t[j][1] += w2*dely*dely; + lambda_t[j][2] += w2*delz*delz; + lambda_t[j][3] += w2*dely*delz; + lambda_t[j][4] += w2*delx*delz; + lambda_t[j][5] += w2*delx*dely; + } + } + } + } + + // wait until all threads are done with computation + sync_threads(); + + // communicate and sum densities + + if (NEWTON_PAIR) { + // reduce per thread density + data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid); + data_reduce_thr(&(mu[0][0]), nall, comm->nthreads, 3, tid); + data_reduce_thr(&(lambda[0][0]), nall, comm->nthreads, 6, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { comm->reverse_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + } else { + // reduce per thread density + data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid); + data_reduce_thr(&(mu[0][0]), nlocal, comm->nthreads, 3, tid); + data_reduce_thr(&(lambda[0][0]), nlocal, comm->nthreads, 6, tid); + + // wait until reduction is complete + sync_threads(); + } + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + p = rho[i]*rdrho + 1.0; + m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + coeff = frho_spline[type2frho[type[i]]][m]; + fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; + if (EFLAG) { + phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + phi += 0.5*(mu[i][0]*mu[i][0]+mu[i][1]*mu[i][1]+mu[i][2]*mu[i][2]); + phi += 0.5*(lambda[i][0]*lambda[i][0]+lambda[i][1]* + lambda[i][1]+lambda[i][2]*lambda[i][2]); + phi += 1.0*(lambda[i][3]*lambda[i][3]+lambda[i][4]* + lambda[i][4]+lambda[i][5]*lambda[i][5]); + phi -= 1.0/6.0*(lambda[i][0]+lambda[i][1]+lambda[i][2])* + (lambda[i][0]+lambda[i][1]+lambda[i][2]); + if (eflag_global) eng_vdwl_thr[tid] += phi; + if (eflag_atom) eatom_thr[tid][i] += phi; + } + } + + // wait until all theads are done with computation + sync_threads(); + + // communicate derivative of embedding function + // MPI communication only on master thread +#if defined(_OPENMP) +#pragma omp master +#endif + { comm->forward_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + // compute forces on each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + fxtmp = fytmp = fztmp = 0.0; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + jtype = type[j]; + r = sqrt(rsq); + p = r*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // u2 = u + // u2p = u' + // w2 = w + // w2p = w' + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + coeff = rhor_spline[type2rhor[itype][jtype]][m]; + rhoip = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = rhor_spline[type2rhor[jtype][itype]][m]; + rhojp = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = z2r_spline[type2z2r[itype][jtype]][m]; + z2p = (coeff[0]*p + coeff[1])*p + coeff[2]; + z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coeff = u2r_spline[type2u2r[itype][jtype]][m]; + u2p = (coeff[0]*p + coeff[1])*p + coeff[2]; + u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coeff = w2r_spline[type2w2r[itype][jtype]][m]; + w2p = (coeff[0]*p + coeff[1])*p + coeff[2]; + w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + + recip = 1.0/r; + phi = z2*recip; + phip = z2p*recip - phi*recip; + psip = fp[i]*rhojp + fp[j]*rhoip + phip; + fpair = -psip*recip; + + delmux = mu[i][0]-mu[j][0]; + delmuy = mu[i][1]-mu[j][1]; + delmuz = mu[i][2]-mu[j][2]; + trdelmu = delmux*delx+delmuy*dely+delmuz*delz; + sumlamxx = lambda[i][0]+lambda[j][0]; + sumlamyy = lambda[i][1]+lambda[j][1]; + sumlamzz = lambda[i][2]+lambda[j][2]; + sumlamyz = lambda[i][3]+lambda[j][3]; + sumlamxz = lambda[i][4]+lambda[j][4]; + sumlamxy = lambda[i][5]+lambda[j][5]; + tradellam = sumlamxx*delx*delx+sumlamyy*dely*dely+ + sumlamzz*delz*delz+2.0*sumlamxy*delx*dely+ + 2.0*sumlamxz*delx*delz+2.0*sumlamyz*dely*delz; + nu = sumlamxx+sumlamyy+sumlamzz; + + adpx = delmux*u2 + trdelmu*u2p*delx*recip + + 2.0*w2*(sumlamxx*delx+sumlamxy*dely+sumlamxz*delz) + + w2p*delx*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delx; + adpy = delmuy*u2 + trdelmu*u2p*dely*recip + + 2.0*w2*(sumlamxy*delx+sumlamyy*dely+sumlamyz*delz) + + w2p*dely*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*dely; + adpz = delmuz*u2 + trdelmu*u2p*delz*recip + + 2.0*w2*(sumlamxz*delx+sumlamyz*dely+sumlamzz*delz) + + w2p*delz*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delz; + adpx*=-1.0; adpy*=-1.0; adpz*=-1.0; + + fx = delx*fpair+adpx; + fy = dely*fpair+adpy; + fz = delz*fpair+adpz; + + fxtmp += fx; + fytmp += fy; + fztmp += fz; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + } + + if (EFLAG) evdwl = phi; + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0, + fx,fy,fz,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairADPOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairADP::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_adp_omp.h b/src/USER-OMP/pair_adp_omp.h new file mode 100644 index 0000000000..f7d2509cd3 --- /dev/null +++ b/src/USER-OMP/pair_adp_omp.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(adp/omp,PairADPOMP) + +#else + +#ifndef LMP_PAIR_ADP_OMP_H +#define LMP_PAIR_ADP_OMP_H + +#include "pair_adp.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairADPOMP : public PairADP, public ThrOMP { + + public: + PairADPOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double *rho_t, double **mu_t, double **lambda_t, + int iifrom, int iito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_born_coul_long_omp.cpp b/src/USER-OMP/pair_born_coul_long_omp.cpp new file mode 100644 index 0000000000..c277a080c0 --- /dev/null +++ b/src/USER-OMP/pair_born_coul_long_omp.cpp @@ -0,0 +1,199 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_born_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairBornCoulLongOMP::PairBornCoulLongOMP(LAMMPS *lmp) : + PairBornCoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBornCoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairBornCoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,r,rexp,forcecoul,forceborn,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r = sqrt(rsq); + + if (rsq < cut_coulsq) { + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]); + forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv + + born3[itype][jtype]*r2inv*r6inv; + } else forceborn = 0.0; + + fpair = (forcecoul + factor_lj*forceborn)*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = prefactor*erfc; + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv + + d[itype][jtype]*r6inv*r2inv - offset[itype][jtype]; + evdwl *= factor_lj; + } + } else evdwl = 0.0; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBornCoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBornCoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_born_coul_long_omp.h b/src/USER-OMP/pair_born_coul_long_omp.h new file mode 100644 index 0000000000..d6ccbfc680 --- /dev/null +++ b/src/USER-OMP/pair_born_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(born/coul/long/omp,PairBornCoulLongOMP) + +#else + +#ifndef LMP_PAIR_BORN_COUL_LONG_OMP_H +#define LMP_PAIR_BORN_COUL_LONG_OMP_H + +#include "pair_born_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBornCoulLongOMP : public PairBornCoulLong, public ThrOMP { + + public: + PairBornCoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_born_omp.cpp b/src/USER-OMP/pair_born_omp.cpp new file mode 100644 index 0000000000..c39d205c97 --- /dev/null +++ b/src/USER-OMP/pair_born_omp.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_born_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairBornOMP::PairBornOMP(LAMMPS *lmp) : + PairBorn(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBornOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairBornOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,r,rexp,forceborn,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + r = sqrt(rsq); + rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]); + forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv + + born3[itype][jtype]*r2inv*r6inv; + fpair = factor_lj*forceborn*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv + + d[itype][jtype]*r6inv*r2inv - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBornOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBorn::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_born_omp.h new file mode 100644 index 0000000000..b24de4a577 --- /dev/null +++ b/src/USER-OMP/pair_born_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(born/omp,PairBornOMP) + +#else + +#ifndef LMP_PAIR_BORN_OMP_H +#define LMP_PAIR_BORN_OMP_H + +#include "pair_born.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBornOMP : public PairBorn, public ThrOMP { + + public: + PairBornOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.cpp b/src/USER-OMP/pair_buck_coul_cut_omp.cpp new file mode 100644 index 0000000000..ac47d478a0 --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_cut_omp.cpp @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_buck_coul_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairBuckCoulCutOMP::PairBuckCoulCutOMP(LAMMPS *lmp) : + PairBuckCoulCut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBuckCoulCutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairBuckCoulCutOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r = sqrt(rsq); + + if (rsq < cut_coulsq[itype][jtype]) + forcecoul = qqrd2e * qtmp*q[j]/r; + else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + rexp = exp(-r*rhoinv[itype][jtype]); + forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; + } else forcebuck = 0.0; + + fpair = (forcecoul + factor_lj*forcebuck)*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) + ecoul = factor_coul * qqrd2e * qtmp*q[j]/r; + else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - + offset[itype][jtype]; + evdwl *= factor_lj; + } + } else evdwl = 0.0; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBuckCoulCutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBuckCoulCut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.h b/src/USER-OMP/pair_buck_coul_cut_omp.h new file mode 100644 index 0000000000..a77f3bad24 --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(buck/coul/cut/omp,PairBuckCoulCutOMP) + +#else + +#ifndef LMP_PAIR_BUCK_COUL_CUT_OMP_H +#define LMP_PAIR_BUCK_COUL_CUT_OMP_H + +#include "pair_buck_coul_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBuckCoulCutOMP : public PairBuckCoulCut, public ThrOMP { + + public: + PairBuckCoulCutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_buck_coul_long_omp.cpp b/src/USER-OMP/pair_buck_coul_long_omp.cpp new file mode 100644 index 0000000000..6e7398ca44 --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_long_omp.cpp @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_buck_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairBuckCoulLongOMP::PairBuckCoulLongOMP(LAMMPS *lmp) : + PairBuckCoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBuckCoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairBuckCoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r = sqrt(rsq); + + if (rsq < cut_coulsq) { + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + rexp = exp(-r*rhoinv[itype][jtype]); + forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; + } else forcebuck = 0.0; + + fpair = (forcecoul + factor_lj*forcebuck)*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = prefactor*erfc; + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - + offset[itype][jtype]; + evdwl *= factor_lj; + } + } else evdwl = 0.0; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBuckCoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBuckCoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/pair_buck_coul_long_omp.h new file mode 100644 index 0000000000..2c87904de8 --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP) + +#else + +#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H +#define LMP_PAIR_BUCK_COUL_LONG_OMP_H + +#include "pair_buck_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP { + + public: + PairBuckCoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_buck_coul_omp.cpp b/src/USER-OMP/pair_buck_coul_omp.cpp new file mode 100644 index 0000000000..bd171f628a --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_omp.cpp @@ -0,0 +1,230 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_buck_coul_omp.h" +#include "atom.h" +#include "comm.h" +#include "math_vector.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairBuckCoulOMP::PairBuckCoulOMP(LAMMPS *lmp) : + PairBuckCoul(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBuckCoulOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairBuckCoulOMP::eval(double **f, int iifrom, int iito, int tid) +{ + double evdwl,ecoul,fpair; + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + + double *x0 = x[0]; + double *f0 = f[0], *fi = f0; + + int *ilist = list->ilist; + + // loop over neighbors of my atoms + + int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); + int *jneigh, *jneighn, typei, typej, ni; + double qi, qri, *cutsqi, *cut_bucksqi, + *buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti; + double r, rsq, r2inv, force_coul, force_buck; + double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; + vector xi, d; + + for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms + i = ilist[ii]; fi = f0+3*i; + if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants + offseti = offset[typei = type[i]]; + buck1i = buck1[typei]; buck2i = buck2[typei]; + buckai = buck_a[typei]; buckci = buck_c[typei], rhoinvi = rhoinv[typei]; + cutsqi = cutsq[typei]; cut_bucksqi = cut_bucksq[typei]; + memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); + jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i]; + + for (; jneigh= cutsqi[typej = type[j]]) continue; + r2inv = 1.0/rsq; + r = sqrt(rsq); + + if (order1 && (rsq < cut_coulsq)) { // coulombic + if (!ncoultablebits || rsq <= tabinnersq) { // series real space + register double x = g_ewald*r; + register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x); + if (ni == 0) { + s *= g_ewald*exp(-x*x); + force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; + if (EFLAG) ecoul = t; + } else { // special case + register double f = s*(1.0-special_coul[ni])/r; + s *= g_ewald*exp(-x*x); + force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-f; + if (EFLAG) ecoul = t-f; + } // table real space + } else { + register union_int_float_t t; + t.f = rsq; + register const int k = (t.i & ncoulmask) >> ncoulshiftbits; + register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; + if (ni == 0) { + force_coul = qiqj*(ftable[k]+f*dftable[k]); + if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]); + } + else { // special case + t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); + force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f); + if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f); + } + } + } else force_coul = ecoul = 0.0; + + if (rsq < cut_bucksqi[typej]) { // buckingham + register double rn = r2inv*r2inv*r2inv, + expr = exp(-r*rhoinvi[typej]); + if (order6) { // long-range + register double x2 = g2*rsq, a2 = 1.0/x2; + x2 = a2*exp(-x2)*buckci[typej]; + if (ni == 0) { + force_buck = + r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; + if (EFLAG) evdwl = expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2; + } else { // special case + register double f = special_lj[ni], t = rn*(1.0-f); + force_buck = f*r*expr*buck1i[typej]- + g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej]; + if (EFLAG) evdwl = f*expr*buckai[typej] - + g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej]; + } + } else { // cut + if (ni == 0) { + force_buck = r*expr*buck1i[typej]-rn*buck2i[typej]; + if (EFLAG) evdwl = expr*buckai[typej] - + rn*buckci[typej]-offseti[typej]; + } else { // special case + register double f = special_lj[ni]; + force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]); + if (EFLAG) + evdwl = f*(expr*buckai[typej]-rn*buckci[typej]-offseti[typej]); + } + } + } else force_buck = evdwl = 0.0; + + fpair = (force_coul+force_buck)*r2inv; + + if (NEWTON_PAIR || j < nlocal) { + register double *fj = f0+(j+(j<<1)), f; + fi[0] += f = d[0]*fpair; fj[0] -= f; + fi[1] += f = d[1]*fpair; fj[1] -= f; + fi[2] += f = d[2]*fpair; fj[2] -= f; + } else { + fi[0] += d[0]*fpair; + fi[1] += d[1]*fpair; + fi[2] += d[2]*fpair; + } + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,d[0],d[1],d[2],tid); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBuckCoulOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBuckCoul::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_buck_coul_omp.h b/src/USER-OMP/pair_buck_coul_omp.h new file mode 100644 index 0000000000..dbff9b419a --- /dev/null +++ b/src/USER-OMP/pair_buck_coul_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(buck/coul/omp,PairBuckCoulOMP) + +#else + +#ifndef LMP_PAIR_BUCK_COUL_OMP_H +#define LMP_PAIR_BUCK_COUL_OMP_H + +#include "pair_buck_coul.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBuckCoulOMP : public PairBuckCoul, public ThrOMP { + + public: + PairBuckCoulOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_buck_omp.cpp b/src/USER-OMP/pair_buck_omp.cpp new file mode 100644 index 0000000000..66d8730abd --- /dev/null +++ b/src/USER-OMP/pair_buck_omp.cpp @@ -0,0 +1,165 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_buck_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairBuckOMP::PairBuckOMP(LAMMPS *lmp) : + PairBuck(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairBuckOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairBuckOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,r,rexp,forcebuck,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + r = sqrt(rsq); + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + r = sqrt(rsq); + rexp = exp(-r*rhoinv[itype][jtype]); + forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; + fpair = factor_lj*forcebuck*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - + offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairBuckOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairBuck::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_buck_omp.h b/src/USER-OMP/pair_buck_omp.h new file mode 100644 index 0000000000..40b6702e6f --- /dev/null +++ b/src/USER-OMP/pair_buck_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(buck/omp,PairBuckOMP) + +#else + +#ifndef LMP_PAIR_BUCK_OMP_H +#define LMP_PAIR_BUCK_OMP_H + +#include "pair_buck.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairBuckOMP : public PairBuck, public ThrOMP { + + public: + PairBuckOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_cdeam_omp.cpp b/src/USER-OMP/pair_cdeam_omp.cpp new file mode 100644 index 0000000000..01bd5f6eaa --- /dev/null +++ b/src/USER-OMP/pair_cdeam_omp.cpp @@ -0,0 +1,545 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" + +#include "pair_cdeam_omp.h" +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +// This is for debugging purposes. The ASSERT() macro is used in the code to check +// if everything runs as expected. Change this to #if 0 if you don't need the checking. +#if 0 + #define ASSERT(cond) ((!(cond)) ? my_failure(error,__FILE__,__LINE__) : my_noop()) + + inline void my_noop() {} + inline void my_failure(Error* error, const char* file, int line) { + char str[1024]; + sprintf(str,"Assertion failure: File %s, line %i", file, line); + error->one(FLERR,str); + } +#else + #define ASSERT(cond) +#endif + +/* ---------------------------------------------------------------------- */ + +PairCDEAMOMP::PairCDEAMOMP(LAMMPS *lmp, int _cdeamVersion) : + PairCDEAM(lmp,_cdeamVersion), PairEAM(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairCDEAMOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow energy and fp arrays if necessary + // need to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(rho); + memory->destroy(rhoB); + memory->destroy(D_values); + memory->destroy(fp); + nmax = atom->nmax; + memory->create(rho,nthreads*nmax,"pair:rho"); + memory->create(rhoB,nthreads*nmax,"pair:mu"); + memory->create(D_values,nthreads*nmax,"pair:D_values"); + memory->create(fp,nmax,"pair:fp"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, *rho_t, *rhoB_t, *D_values_t; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + if (force->newton_pair) { + rho_t = rho + tid*nall; + rhoB_t = rhoB + tid*nall; + D_values_t = D_values + tid*nall; + } else { + rho_t = rho + tid*atom->nlocal; + rhoB_t = rhoB + tid*atom->nlocal; + D_values_t = D_values + tid*atom->nlocal; + } + + switch (cdeamVersion) { + + case 1: + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<1,1,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<1,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<0,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } + break; + + case 2: + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<1,1,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<1,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + else eval<0,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid); + } + break; + + default: +#if defined(_OPENMP) +#pragma omp master +#endif + error->all(FLERR,"unsupported eam/cd pair style variant"); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairCDEAMOMP::eval(double **f, double *rho_t, double *rhoB_t, + double *D_values_t, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,rhoip,rhojp,recip,phi; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // zero out density + + if (NEWTON_PAIR) { + memset(rho_t, 0, nall*sizeof(double)); + memset(rhoB_t, 0, nall*sizeof(double)); + memset(D_values_t, 0, nall*sizeof(double)); + } else { + memset(rho_t, 0, nlocal*sizeof(double)); + memset(rhoB_t, 0, nlocal*sizeof(double)); + memset(D_values_t, 0, nlocal*sizeof(double)); + } + + // Stage I + + // Compute rho and rhoB at each local atom site. + // Additionally calculate the D_i values here if we are using the one-site formulation. + // For the two-site formulation we have to calculate the D values in an extra loop (Stage II). + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + 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]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < cutforcesq) { + jtype = type[j]; + double r = sqrt(rsq); + const EAMTableIndex index = radiusToTableIndex(r); + double localrho = RhoOfR(index, jtype, itype); + rho_t[i] += localrho; + if(jtype == speciesB) rhoB_t[i] += localrho; + if(NEWTON_PAIR || j < nlocal) { + localrho = RhoOfR(index, itype, jtype); + rho_t[j] += localrho; + if(itype == speciesB) rhoB_t[j] += localrho; + } + + if(CDEAMVERSION == 1 && itype != jtype) { + // Note: if the i-j interaction is not concentration dependent (because either + // i or j are not species A or B) then its contribution to D_i and D_j should + // be ignored. + // This if-clause is only required for a ternary. + if((itype == speciesA && jtype == speciesB) + || (jtype == speciesA && itype == speciesB)) { + double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r); + D_values_t[i] += Phi_AB; + if(NEWTON_PAIR || j < nlocal) + D_values_t[j] += Phi_AB; + } + } + } + } + } + + // wait until all threads are done with computation + sync_threads(); + + // communicate and sum densities + + if (NEWTON_PAIR) { + // reduce per thread density + data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid); + data_reduce_thr(&(rhoB[0]), nall, comm->nthreads, 1, tid); + if (CDEAMVERSION==1) + data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { communicationStage = 1; + comm->reverse_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + } else { + // reduce per thread density + data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid); + data_reduce_thr(&(rhoB[0]), nlocal, comm->nthreads, 1, tid); + if (CDEAMVERSION==1) + data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + } + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + EAMTableIndex index = rhoToTableIndex(rho[i]); + fp[i] = FPrimeOfRho(index, type[i]); + if(EFLAG) { + phi = FofRho(index, type[i]); + if (eflag_global) eng_vdwl_thr[tid] += phi; + if (eflag_atom) eatom_thr[tid][i] += phi; + } + } + + // wait until all theads are done with computation + sync_threads(); + + // Communicate derivative of embedding function and densities + // and D_values (this for one-site formulation only). +#if defined(_OPENMP) +#pragma omp master +#endif + { communicationStage = 2; + comm->forward_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + + // The electron densities may not drop to zero because then the concentration would no longer be defined. + // But the concentration is not needed anyway if there is no interaction with another atom, which is the case + // if the electron density is exactly zero. That's why the following lines have been commented out. + // + //for(i = 0; i < nlocal + atom->nghost; i++) { + // if(rho[i] == 0 && (type[i] == speciesA || type[i] == speciesB)) + // error->one(FLERR,"CD-EAM potential routine: Detected atom with zero electron density."); + //} + + // Stage II + // This is only required for the original two-site formulation of the CD-EAM potential. + + if(CDEAMVERSION == 2) { + // Compute intermediate value D_i for each atom. + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + // This code line is required for ternary alloys. + if(itype != speciesA && itype != speciesB) continue; + + double x_i = rhoB[i] / rho[i]; // Concentration at atom i. + + for(jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + if(itype == jtype) continue; + + // This code line is required for ternary alloys. + if(jtype != speciesA && jtype != speciesB) 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 < cutforcesq) { + double r = sqrt(rsq); + const EAMTableIndex index = radiusToTableIndex(r); + + // The concentration independent part of the cross pair potential. + double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r); + + // Average concentration of two sites + double x_ij = 0.5 * (x_i + rhoB[j]/rho[j]); + + // Calculate derivative of h(x_ij) polynomial function. + double h_prime = evalHprime(x_ij); + + D_values_t[i] += h_prime * Phi_AB / (2.0 * rho[i] * rho[i]); + if(NEWTON_PAIR || j < nlocal) + D_values_t[j] += h_prime * Phi_AB / (2.0 * rho[j] * rho[j]); + } + } + } + + if (NEWTON_PAIR) { + data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { communicationStage = 3; + comm->reverse_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + } else { + data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + } + +#if defined(_OPENMP) +#pragma omp master +#endif + { communicationStage = 4; + comm->forward_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + } + + // Stage III + + // Compute force acting on each atom. + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + fxtmp = fytmp = fztmp = 0.0; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + // Concentration at site i + double x_i = -1.0; // The value -1 indicates: no concentration dependence for all interactions of atom i. + // It will be replaced by the concentration at site i if atom i is either A or B. + + double D_i, h_prime_i; + + // This if-clause is only required for ternary alloys. + if((itype == speciesA || itype == speciesB) && rho[i] != 0.0) { + + // Compute local concentration at site i. + x_i = rhoB[i]/rho[i]; + ASSERT(x_i >= 0 && x_i<=1.0); + + if(CDEAMVERSION == 1) { + // Calculate derivative of h(x_i) polynomial function. + h_prime_i = evalHprime(x_i); + D_i = D_values[i] * h_prime_i / (2.0 * rho[i] * rho[i]); + } else if(CDEAMVERSION == 2) { + D_i = D_values[i]; + } else ASSERT(false); + } + + for(jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < cutforcesq) { + jtype = type[j]; + double r = sqrt(rsq); + const EAMTableIndex index = radiusToTableIndex(r); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + rhoip = RhoPrimeOfR(index, itype, jtype); + rhojp = RhoPrimeOfR(index, jtype, itype); + fpair = fp[i]*rhojp + fp[j]*rhoip; + recip = 1.0/r; + + double x_j = -1; // The value -1 indicates: no concentration dependence for this i-j pair + // because atom j is not of species A nor B. + + // This code line is required for ternary alloy. + if(jtype == speciesA || jtype == speciesB) { + ASSERT(rho[i] != 0.0); + ASSERT(rho[j] != 0.0); + + // Compute local concentration at site j. + x_j = rhoB[j]/rho[j]; + ASSERT(x_j >= 0 && x_j<=1.0); + + double D_j; + if(CDEAMVERSION == 1) { + // Calculate derivative of h(x_j) polynomial function. + double h_prime_j = evalHprime(x_j); + D_j = D_values[j] * h_prime_j / (2.0 * rho[j] * rho[j]); + } else if(CDEAMVERSION == 2) { + D_j = D_values[j]; + } else ASSERT(false); + + double t2 = -rhoB[j]; + if(itype == speciesB) t2 += rho[j]; + fpair += D_j * rhoip * t2; + } + + // This if-clause is only required for a ternary alloy. + // Actually we don't need it at all because D_i should be zero anyway if + // atom i has no concentration dependent interactions (because it is not species A or B). + if(x_i != -1.0) { + double t1 = -rhoB[i]; + if(jtype == speciesB) t1 += rho[i]; + fpair += D_i * rhojp * t1; + } + + double phip; + double phi = PhiOfR(index, itype, jtype, recip, phip); + if(itype == jtype || x_i == -1.0 || x_j == -1.0) { + // Case of no concentration dependence. + fpair += phip; + } else { + // We have a concentration dependence for the i-j interaction. + double h; + if(CDEAMVERSION == 1) { + // Calculate h(x_i) polynomial function. + double h_i = evalH(x_i); + // Calculate h(x_j) polynomial function. + double h_j = evalH(x_j); + h = 0.5 * (h_i + h_j); + } else if(CDEAMVERSION == 2) { + // Average concentration. + double x_ij = 0.5 * (x_i + x_j); + // Calculate h(x_ij) polynomial function. + h = evalH(x_ij); + } else ASSERT(false); + + fpair += h * phip; + phi *= h; + } + + // Divide by r_ij and negate to get forces from gradient. + fpair /= -r; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if(NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if(EFLAG) evdwl = phi; + if(EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0, + fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairCDEAMOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairCDEAM::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_cdeam_omp.h b/src/USER-OMP/pair_cdeam_omp.h new file mode 100644 index 0000000000..85b124cb17 --- /dev/null +++ b/src/USER-OMP/pair_cdeam_omp.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/cd/omp,PairCDEAM_OneSiteOMP) +PairStyle(eam/cd/old/omp,PairCDEAM_TwoSiteOMP) + +#else + +#ifndef LMP_PAIR_CDEAM_OMP_H +#define LMP_PAIR_CDEAM_OMP_H + +#include "pair_cdeam.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairCDEAMOMP : public PairCDEAM, public ThrOMP { + + public: + PairCDEAMOMP(class LAMMPS *, int); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double *rho_t, double *rhoB_t, double *D_values_t, + int iifrom, int iito, int tid); +}; + + /// The one-site concentration formulation of CD-EAM. + class PairCDEAM_OneSiteOMP : public PairCDEAMOMP + { + public: + /// Constructor. + PairCDEAM_OneSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 1) {} + }; + + /// The two-site concentration formulation of CD-EAM. + class PairCDEAM_TwoSiteOMP : public PairCDEAMOMP + { + public: + /// Constructor. + PairCDEAM_TwoSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 2) {} + }; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_colloid_omp.cpp b/src/USER-OMP/pair_colloid_omp.cpp new file mode 100644 index 0000000000..c8bc74407a --- /dev/null +++ b/src/USER-OMP/pair_colloid_omp.cpp @@ -0,0 +1,223 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_colloid_omp.h" +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairColloidOMP::PairColloidOMP(LAMMPS *lmp) : + PairColloid(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairColloidOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairColloidOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,r2inv,r6inv,forcelj,factor_lj; + double c1,c2,fR,dUR,dUA,K[9],h[4],g[4]; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) continue; + + switch(form[itype][jtype]) { + case SMALL_SMALL: + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = factor_lj*forcelj*r2inv; + if (EFLAG) + evdwl = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) - + offset[itype][jtype]; + break; + + case SMALL_LARGE: + c2 = a2[itype][jtype]; + K[1] = c2*c2; + K[2] = rsq; + K[0] = K[1] - rsq; + K[4] = rsq*rsq; + K[3] = K[1] - K[2]; + K[3] *= K[3]*K[3]; + K[6] = K[3]*K[3]; + fR = sigma3[itype][jtype]*a12[itype][jtype]*c2*K[1]/K[3]; + fpair = 4.0/15.0*fR*factor_lj * + (2.0*(K[1]+K[2]) * (K[1]*(5.0*K[1]+22.0*K[2])+5.0*K[4]) * + sigma6[itype][jtype]/K[6]-5.0) / K[0]; + if (EFLAG) + evdwl = 2.0/9.0*fR * + (1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) * + sigma6[itype][jtype]/K[6]) - offset[itype][jtype]; + if (rsq <= K[1]) error->one(FLERR,"Overlapping small/large in pair colloid"); + break; + + case LARGE_LARGE: + r = sqrt(rsq); + c1 = a1[itype][jtype]; + c2 = a2[itype][jtype]; + K[0] = c1*c2; + K[1] = c1+c2; + K[2] = c1-c2; + K[3] = K[1]+r; + K[4] = K[1]-r; + K[5] = K[2]+r; + K[6] = K[2]-r; + K[7] = 1.0/(K[3]*K[4]); + K[8] = 1.0/(K[5]*K[6]); + g[0] = pow(K[3],-7.0); + g[1] = pow(K[4],-7.0); + g[2] = pow(K[5],-7.0); + g[3] = pow(K[6],-7.0); + h[0] = ((K[3]+5.0*K[1])*K[3]+30.0*K[0])*g[0]; + h[1] = ((K[4]+5.0*K[1])*K[4]+30.0*K[0])*g[1]; + h[2] = ((K[5]+5.0*K[2])*K[5]-30.0*K[0])*g[2]; + h[3] = ((K[6]+5.0*K[2])*K[6]-30.0*K[0])*g[3]; + g[0] *= 42.0*K[0]/K[3]+6.0*K[1]+K[3]; + g[1] *= 42.0*K[0]/K[4]+6.0*K[1]+K[4]; + g[2] *= -42.0*K[0]/K[5]+6.0*K[2]+K[5]; + g[3] *= -42.0*K[0]/K[6]+6.0*K[2]+K[6]; + + fR = a12[itype][jtype]*sigma6[itype][jtype]/r/37800.0; + evdwl = fR * (h[0]-h[1]-h[2]+h[3]); + dUR = evdwl/r + 5.0*fR*(g[0]+g[1]-g[2]-g[3]); + dUA = -a12[itype][jtype]/3.0*r*((2.0*K[0]*K[7]+1.0)*K[7] + + (2.0*K[0]*K[8]-1.0)*K[8]); + fpair = factor_lj * (dUR+dUA)/r; + if (EFLAG) + evdwl += a12[itype][jtype]/6.0 * + (2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - offset[itype][jtype]; + if (r <= K[1]) error->one(FLERR,"Overlapping large/large in pair colloid"); + break; + } + + if (EFLAG) evdwl *= factor_lj; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairColloidOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairColloid::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_colloid_omp.h b/src/USER-OMP/pair_colloid_omp.h new file mode 100644 index 0000000000..a0be13cbb4 --- /dev/null +++ b/src/USER-OMP/pair_colloid_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(colloid/omp,PairColloidOMP) + +#else + +#ifndef LMP_PAIR_COLLOID_OMP_H +#define LMP_PAIR_COLLOID_OMP_H + +#include "pair_colloid.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairColloidOMP : public PairColloid, public ThrOMP { + + public: + PairColloidOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp new file mode 100644 index 0000000000..207c122e45 --- /dev/null +++ b/src/USER-OMP/pair_comb_omp.cpp @@ -0,0 +1,540 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_comb_omp.h" +#include "atom.h" +#include "comm.h" +#include "group.h" +#include "force.h" +#include "memory.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairCombOMP::PairCombOMP(LAMMPS *lmp) : + PairComb(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairCombOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = vflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow coordination array if necessary + + if (atom->nmax > nmax) { + memory->destroy(NCo); + nmax = atom->nmax; + memory->create(NCo,nmax,"pair:NCo"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else eval<0,0,0>(f, ifrom, ito, tid); + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairCombOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,ii,jj,kk,jnum,iparam_i; + int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,rsq1,rsq2; + double delr1[3],delr2[3],fi[3],fj[3],fk[3]; + double zeta_ij,prefactor; + int *ilist,*jlist,*numneigh,**firstneigh; + int mr1,mr2,mr3; + int rsc,inty; + double elp_ij,filp[3],fjlp[3],fklp[3]; + double iq,jq; + double yaself; + double potal,fac11,fac11e; + double vionij,fvionij,sr1,sr2,sr3,Eov,Fov; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + yaself = vionij = fvionij = Eov = Fov = 0.0; + + double fxtmp,fytmp,fztmp; + double fjxtmp,fjytmp,fjztmp; + + // self energy correction term: potal + + potal_calc(potal,fac11,fac11e); + + // loop over full neighbor list of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itag = tag[i]; + itype = map[type[i]]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + fxtmp = fytmp = fztmp = 0.0; + + iq = q[i]; + NCo[i] = 0; + iparam_i = elem2param[itype][itype][itype]; + + // self energy, only on i atom + + yaself = self(¶ms[iparam_i],iq,potal); + + if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,yaself, + 0.0,0.0,0.0,0.0,0.0,tid); + + // two-body interactions (long and short repulsive) + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + 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; + if (x[j][2] == ztmp && x[j][1] < ytmp) continue; + if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + + // Qj calculates 2-body Coulombic + + jtype = map[type[j]]; + jq = q[j]; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + iparam_ij = elem2param[itype][jtype][jtype]; + + // long range q-dependent + + if (rsq > params[iparam_ij].lcutsq) continue; + + inty = intype[itype][jtype]; + + // polynomial three-point interpolation + + tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype); + + // 1/r energy and forces + + direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq, + potal,fac11,fac11e,vionij,fvionij); + + // field correction to self energy + + field(¶ms[iparam_ij],rsq,iq,jq,vionij,fvionij); + + // polarization field + // sums up long range forces + + fxtmp += delx*fvionij; + fytmp += dely*fvionij; + fztmp += delz*fvionij; + f[j][0] -= delx*fvionij; + f[j][1] -= dely*fvionij; + f[j][2] -= delz*fvionij; + + if (EVFLAG) + ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, + 0.0,vionij,fvionij,delx,dely,delz,tid); + + // short range q-independent + + if (rsq > params[iparam_ij].cutsq) continue; + + repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl,iq,jq); + + // repulsion is pure two-body, sums up pair repulsive forces + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + + if (EVFLAG) + ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + + // accumulate coordination number information + + if (cor_flag) { + int numcoor = 0; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = map[type[j]]; + iparam_ij = elem2param[itype][jtype][jtype]; + + if(params[iparam_ij].hfocor > 0.0 ) { + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + rsq1 = vec3_dot(delr1,delr1); + + if (rsq1 > params[iparam_ij].cutsq) continue; + ++numcoor; + } + NCo[i] = numcoor; + } + } + + // three-body interactions + // skip immediately if I-J is not within cutoff + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = map[type[j]]; + iparam_ij = elem2param[itype][jtype][jtype]; + + // this Qj for q-dependent BSi + + jq = q[j]; + + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + rsq1 = vec3_dot(delr1,delr1); + + if (rsq1 > params[iparam_ij].cutsq) continue; + + // accumulate bondorder zeta for each i-j interaction via loop over k + + fjxtmp = fjytmp = fjztmp = 0.0; + zeta_ij = 0.0; + cuo_flag1 = 0; cuo_flag2 = 0; + + for (kk = 0; kk < jnum; kk++) { + if (jj == kk) continue; + k = jlist[kk]; + k &= NEIGHMASK; + ktype = map[type[k]]; + iparam_ijk = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + rsq2 = vec3_dot(delr2,delr2); + + if (rsq2 > params[iparam_ijk].cutsq) continue; + + zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); + + if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1; + if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1; + } + + if (cuo_flag1 && cuo_flag2) cuo_flag = 1; + else cuo_flag = 0; + + // pairwise force due to zeta + + force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair, + prefactor,EFLAG,evdwl,iq,jq); + + // over-coordination correction for HfO2 + + if (cor_flag && NCo[i] != 0) + Over_cor(¶ms[iparam_ij],rsq1,NCo[i],Eov, Fov); + evdwl += Eov; + fpair += Fov; + + fxtmp += delr1[0]*fpair; + fytmp += delr1[1]*fpair; + fztmp += delr1[2]*fpair; + fjxtmp -= delr1[0]*fpair; + fjytmp -= delr1[1]*fpair; + fjztmp -= delr1[2]*fpair; + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0, + -fpair,-delr1[0],-delr1[1],-delr1[2],tid); + + // attractive term via loop over k (3-body forces) + + for (kk = 0; kk < jnum; kk++) { + if (jj == kk) continue; + k = jlist[kk]; + k &= NEIGHMASK; + ktype = map[type[k]]; + iparam_ijk = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + rsq2 = vec3_dot(delr2,delr2); + if (rsq2 > params[iparam_ijk].cutsq) continue; + + for (rsc = 0; rsc < 3; rsc++) + fi[rsc] = fj[rsc] = fk[rsc] = 0.0; + + attractive(¶ms[iparam_ijk],prefactor, + rsq1,rsq2,delr1,delr2,fi,fj,fk); + + // 3-body LP and BB correction and forces + + elp_ij = elp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); + flp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp); + + fxtmp += fi[0] + filp[0]; + fytmp += fi[1] + filp[1]; + fztmp += fi[2] + filp[2]; + fjxtmp += fj[0] + fjlp[0]; + fjytmp += fj[1] + fjlp[1]; + fjztmp += fj[2] + fjlp[2]; + f[k][0] += fk[0] + fklp[0]; + f[k][1] += fk[1] + fklp[1]; + f[k][2] += fk[2] + fklp[2]; + + if (EVFLAG) + ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, + elp_ij,0.0,0.0,0.0,0.0,0.0, tid); + if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid); + } + f[j][0] += fjxtmp; + f[j][1] += fjytmp; + f[j][2] += fjztmp; + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + + if (cuo_flag) params[iparam_i].cutsq *= 0.65; + } + cuo_flag = 0; +} + +/* ---------------------------------------------------------------------- */ + +double PairCombOMP::yasu_char(double *qf_fix, int &igroup) +{ + int ii; + double potal,fac11,fac11e; + + const double * const * const x = atom->x; + const double * const q = atom->q; + const int * const type = atom->type; + + const int inum = list->inum; + const int * const ilist = list->ilist; + const int * const numneigh = list->numneigh; + const int * const * const firstneigh = list->firstneigh; + + const int * const mask = atom->mask; + const int groupbit = group->bitmask[igroup]; + + qf = qf_fix; + for (ii = 0; ii < inum; ii++) { + const int i = ilist[ii]; + if (mask[i] & groupbit) + qf[i] = 0.0; + } + + // communicating charge force to all nodes, first forward then reverse + + comm->forward_comm_pair(this); + + // self energy correction term: potal + + potal_calc(potal,fac11,fac11e); + + // loop over full neighbor list of my atoms +#if defined(_OPENMP) +#pragma omp parallel for private(ii) default(none) shared(potal,fac11e) +#endif + for (ii = 0; ii < inum; ii ++) { + double fqi,fqj,fqij,fqji,fqjj,delr1[3],delr2[3]; + double sr1,sr2,sr3; + int mr1,mr2,mr3; + + const int i = ilist[ii]; + + if (mask[i] & groupbit) { + fqi = fqj = fqij = fqji = fqjj = 0.0; // should not be needed. + int itype = map[type[i]]; + const double xtmp = x[i][0]; + const double ytmp = x[i][1]; + const double ztmp = x[i][2]; + const double iq = q[i]; + const int iparam_i = elem2param[itype][itype][itype]; + + // charge force from self energy + + fqi = qfo_self(¶ms[iparam_i],iq,potal); + + // two-body interactions + + const int * const jlist = firstneigh[i]; + const int jnum = numneigh[i]; + + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj] & NEIGHMASK; + const int jtype = map[type[j]]; + double jq = q[j]; + + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + double rsq1 = vec3_dot(delr1,delr1); + + const int iparam_ij = elem2param[itype][jtype][jtype]; + + // long range q-dependent + + if (rsq1 > params[iparam_ij].lcutsq) continue; + + const int inty = intype[itype][jtype]; + + // polynomial three-point interpolation + + tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype); + + // 1/r charge forces + + qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij); + + // field correction to self energy and charge force + + qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqji,fqjj); + fqi += jq * fqij + fqji; +#if defined(_OPENMP) +#pragma omp atomic +#endif + qf[j] += (iq * fqij + fqjj); + + // polarization field charge force + // three-body interactions + + if (rsq1 > params[iparam_ij].cutsq) continue; + + double zeta_ij = 0.0; + + for (int kk = 0; kk < jnum; kk++) { + if (jj == kk) continue; + const int k = jlist[kk] & NEIGHMASK; + const int ktype = map[type[k]]; + const int iparam_ijk = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + const double rsq2 = vec3_dot(delr2,delr2); + + if (rsq2 > params[iparam_ijk].cutsq) continue; + zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); + } + + // charge force in Aij and Bij + + qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj); + fqi += fqij; +#if defined(_OPENMP) +#pragma omp atomic +#endif + qf[j] += fqjj; + } + +#if defined(_OPENMP) +#pragma omp atomic +#endif + qf[i] += fqi; + + } + } + + comm->reverse_comm_pair(this); + + // sum charge force on each node and return it + + double eneg = 0.0; + for (ii = 0; ii < inum; ii++) { + const int i = ilist[ii]; + if (mask[i] & groupbit) + eneg += qf[i]; + } + double enegtot; + MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world); + return enegtot; +} + +/* ---------------------------------------------------------------------- */ + +double PairCombOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairComb::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_comb_omp.h b/src/USER-OMP/pair_comb_omp.h new file mode 100644 index 0000000000..6f020ea9ab --- /dev/null +++ b/src/USER-OMP/pair_comb_omp.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(comb/omp,PairCombOMP) + +#else + +#ifndef LMP_PAIR_COMB_OMP_H +#define LMP_PAIR_COMB_OMP_H + +#include "pair_comb.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairCombOMP : public PairComb, public ThrOMP { + + public: + PairCombOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + virtual double yasu_char(double *, int &); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_coul_cut_omp.cpp b/src/USER-OMP/pair_coul_cut_omp.cpp new file mode 100644 index 0000000000..bb19db3d22 --- /dev/null +++ b/src/USER-OMP/pair_coul_cut_omp.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_coul_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairCoulCutOMP::PairCoulCutOMP(LAMMPS *lmp) : + PairCoulCut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulCutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairCoulCutOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; + double rsq,r2inv,rinv,forcecoul,factor_coul; + int *ilist,*jlist,*numneigh,**firstneigh; + + ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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 * scale[itype][jtype] * qtmp*q[j]*rinv; + fpair = factor_coul*forcecoul * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) + ecoul = factor_coul * qqrd2e * scale[itype][jtype] * qtmp*q[j]*rinv; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + 0.0,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairCoulCutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairCoulCut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_coul_cut_omp.h b/src/USER-OMP/pair_coul_cut_omp.h new file mode 100644 index 0000000000..eca9958ff2 --- /dev/null +++ b/src/USER-OMP/pair_coul_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(coul/cut/omp,PairCoulCutOMP) + +#else + +#ifndef LMP_PAIR_COUL_CUT_OMP_H +#define LMP_PAIR_COUL_CUT_OMP_H + +#include "pair_coul_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairCoulCutOMP : public PairCoulCut, public ThrOMP { + + public: + PairCoulCutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_coul_debye_omp.cpp b/src/USER-OMP/pair_coul_debye_omp.cpp new file mode 100644 index 0000000000..1c2e7b8e07 --- /dev/null +++ b/src/USER-OMP/pair_coul_debye_omp.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_coul_debye_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairCoulDebyeOMP::PairCoulDebyeOMP(LAMMPS *lmp) : + PairCoulDebye(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulDebyeOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; + double rsq,r2inv,r,rinv,forcecoul,factor_coul,screening; + int *ilist,*jlist,*numneigh,**firstneigh; + + ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r = sqrt(rsq); + rinv = 1.0/r; + screening = exp(-kappa*r); + forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv); + fpair = factor_coul*forcecoul * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) + ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + 0.0,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ +double PairCoulDebyeOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairCoulDebye::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_coul_debye_omp.h b/src/USER-OMP/pair_coul_debye_omp.h new file mode 100644 index 0000000000..7ad599bb1b --- /dev/null +++ b/src/USER-OMP/pair_coul_debye_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(coul/debye/omp,PairCoulDebyeOMP) + +#else + +#ifndef LMP_PAIR_COUL_DEBYE_OMP_H +#define LMP_PAIR_COUL_DEBYE_OMP_H + +#include "pair_coul_debye.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairCoulDebyeOMP : public PairCoulDebye, public ThrOMP { + + public: + PairCoulDebyeOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_coul_long_omp.cpp b/src/USER-OMP/pair_coul_long_omp.cpp new file mode 100644 index 0000000000..3a2e051591 --- /dev/null +++ b/src/USER-OMP/pair_coul_long_omp.cpp @@ -0,0 +1,201 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairCoulLongOMP::PairCoulLongOMP(LAMMPS *lmp) : + PairCoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairCoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itable,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; + double fraction,table; + double r,r2inv,rsq,forcecoul,factor_coul; + double grij,expm2,prefactor,t,erfc; + int *ilist,*jlist,*numneigh,**firstneigh; + + ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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 < cut_coulsq) { + r2inv = 1.0/rsq; + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = scale[itype][jtype] * qtmp*q[j] * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = scale[itype][jtype] * qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + + fpair = forcecoul * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = scale[itype][jtype] * qtmp*q[j] * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + 0.0,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairCoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairCoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_coul_long_omp.h b/src/USER-OMP/pair_coul_long_omp.h new file mode 100644 index 0000000000..7b63f762f2 --- /dev/null +++ b/src/USER-OMP/pair_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(coul/long/omp,PairCoulLongOMP) + +#else + +#ifndef LMP_PAIR_COUL_LONG_OMP_H +#define LMP_PAIR_COUL_LONG_OMP_H + +#include "pair_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairCoulLongOMP : public PairCoulLong, public ThrOMP { + + public: + PairCoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_dipole_cut_omp.cpp b/src/USER-OMP/pair_dipole_cut_omp.cpp new file mode 100644 index 0000000000..9ba93b19b5 --- /dev/null +++ b/src/USER-OMP/pair_dipole_cut_omp.cpp @@ -0,0 +1,288 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_dipole_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairDipoleCutOMP::PairDipoleCutOMP(LAMMPS *lmp) : + PairDipoleCut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairDipoleCutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid); + else eval<1,1,0>(f, torque, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid); + else eval<1,0,0>(f, torque, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid); + else eval<0,0,0>(f, torque, ifrom, ito, tid); + } + + // reduce per thread forces and torques into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairDipoleCutOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul; + double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv,fx,fy,fz; + double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz; + double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul; + double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4; + double forcelj,factor_coul,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + double *q = atom->q; + double **mu = atom->mu; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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); + + // atom can have both a charge and dipole + // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole + + forcecoulx = forcecouly = forcecoulz = 0.0; + tixcoul = tiycoul = tizcoul = 0.0; + tjxcoul = tjycoul = tjzcoul = 0.0; + + if (rsq < cut_coulsq[itype][jtype]) { + + if (qtmp != 0.0 && q[j] != 0.0) { + r3inv = r2inv*rinv; + pre1 = qtmp*q[j]*r3inv; + + forcecoulx += pre1*delx; + forcecouly += pre1*dely; + forcecoulz += pre1*delz; + } + + if (mu[i][3] > 0.0 && mu[j][3] > 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + r7inv = r5inv*r2inv; + + pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2]; + pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz; + pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz; + + pre1 = 3.0*r5inv*pdotp - 15.0*r7inv*pidotr*pjdotr; + pre2 = 3.0*r5inv*pjdotr; + pre3 = 3.0*r5inv*pidotr; + pre4 = -1.0*r3inv; + + forcecoulx += pre1*delx + pre2*mu[i][0] + pre3*mu[j][0]; + forcecouly += pre1*dely + pre2*mu[i][1] + pre3*mu[j][1]; + forcecoulz += pre1*delz + pre2*mu[i][2] + pre3*mu[j][2]; + + crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]); + crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]); + crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]); + + tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely); + tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz); + tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx); + tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely); + tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz); + tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx); + } + + if (mu[i][3] > 0.0 && q[j] != 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz; + pre1 = 3.0*q[j]*r5inv * pidotr; + pre2 = q[j]*r3inv; + + forcecoulx += pre2*mu[i][0] - pre1*delx; + forcecouly += pre2*mu[i][1] - pre1*dely; + forcecoulz += pre2*mu[i][2] - pre1*delz; + tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely); + tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz); + tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx); + } + + if (mu[j][3] > 0.0 && qtmp != 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz; + pre1 = 3.0*qtmp*r5inv * pjdotr; + pre2 = qtmp*r3inv; + + forcecoulx += pre1*delx - pre2*mu[j][0]; + forcecouly += pre1*dely - pre2*mu[j][1]; + forcecoulz += pre1*delz - pre2*mu[j][2]; + tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely); + tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz); + tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx); + } + } + + // LJ interaction + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= factor_lj * r2inv; + } else forcelj = 0.0; + + // total force + + fq = factor_coul*qqrd2e; + fx = fq*forcecoulx + delx*forcelj; + fy = fq*forcecouly + dely*forcelj; + fz = fq*forcecoulz + delz*forcelj; + + // force & torque accumulation + + fxtmp += fx; + fytmp += fy; + fztmp += fz; + t1tmp += fq*tixcoul; + t2tmp += fq*tiycoul; + t3tmp += fq*tizcoul; + + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + torque[j][0] += fq*tjxcoul; + torque[j][1] += fq*tjycoul; + torque[j][2] += fq*tjzcoul; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) { + ecoul = qtmp*q[j]*rinv; + if (mu[i][3] > 0.0 && mu[j][3] > 0.0) + ecoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr; + if (mu[i][3] > 0.0 && q[j] != 0.0) + ecoul += -q[j]*r3inv*pidotr; + if (mu[j][3] > 0.0 && qtmp != 0.0) + ecoul += qtmp*r3inv*pjdotr; + ecoul *= factor_coul*qqrd2e; + } else ecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + torque[i][0] += t1tmp; + torque[i][1] += t2tmp; + torque[i][2] += t3tmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairDipoleCutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairDipoleCut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_dipole_cut_omp.h b/src/USER-OMP/pair_dipole_cut_omp.h new file mode 100644 index 0000000000..832bd4d3be --- /dev/null +++ b/src/USER-OMP/pair_dipole_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dipole/cut/omp,PairDipoleCutOMP) + +#else + +#ifndef LMP_PAIR_DIPOLE_CUT_OMP_H +#define LMP_PAIR_DIPOLE_CUT_OMP_H + +#include "pair_dipole_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairDipoleCutOMP : public PairDipoleCut, public ThrOMP { + + public: + PairDipoleCutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_dipole_sf_omp.cpp b/src/USER-OMP/pair_dipole_sf_omp.cpp new file mode 100644 index 0000000000..9ebc72d414 --- /dev/null +++ b/src/USER-OMP/pair_dipole_sf_omp.cpp @@ -0,0 +1,320 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_dipole_sf_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairDipoleSFOMP::PairDipoleSFOMP(LAMMPS *lmp) : + PairDipoleSF(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairDipoleSFOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid); + else eval<1,1,0>(f, torque, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid); + else eval<1,0,0>(f, torque, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid); + else eval<0,0,0>(f, torque, ifrom, ito, tid); + } + + // reduce per thread forces and torques into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairDipoleSFOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul; + double rsq,rinv,r2inv,r6inv,r3inv,r5inv,fx,fy,fz; + double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz; + double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul; + double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4; + double forcelj,factor_coul,factor_lj; + double presf,afac,bfac,pqfac,qpfac,forceljcut,forceljsf; + double aforcecoulx,aforcecouly,aforcecoulz; + double bforcecoulx,bforcecouly,bforcecoulz; + double rcutlj2inv, rcutcoul2inv,rcutlj6inv; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + double *q = atom->q; + double **mu = atom->mu; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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); + + // atom can have both a charge and dipole + // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole + // atom can have both a charge and dipole + // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole + + forcecoulx = forcecouly = forcecoulz = 0.0; + tixcoul = tiycoul = tizcoul = 0.0; + tjxcoul = tjycoul = tjzcoul = 0.0; + + if (rsq < cut_coulsq[itype][jtype]) { + + if (qtmp != 0.0 && q[j] != 0.0) { + pre1 = qtmp*q[j]*rinv*(r2inv-1.0/cut_coulsq[itype][jtype]); + + forcecoulx += pre1*delx; + forcecouly += pre1*dely; + forcecoulz += pre1*delz; + } + + if (mu[i][3] > 0.0 && mu[j][3] > 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + rcutcoul2inv=1.0/cut_coulsq[itype][jtype]; + + pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2]; + pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz; + pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz; + + afac = 1.0 - rsq*rsq * rcutcoul2inv*rcutcoul2inv; + pre1 = afac * ( pdotp - 3.0 * r2inv * pidotr * pjdotr ); + aforcecoulx = pre1*delx; + aforcecouly = pre1*dely; + aforcecoulz = pre1*delz; + + bfac = 1.0 - 4.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv) + + 3.0*rsq*rsq*rcutcoul2inv*rcutcoul2inv; + presf = 2.0 * r2inv * pidotr * pjdotr; + bforcecoulx = bfac * (pjdotr*mu[i][0]+pidotr*mu[j][0]-presf*delx); + bforcecouly = bfac * (pjdotr*mu[i][1]+pidotr*mu[j][1]-presf*dely); + bforcecoulz = bfac * (pjdotr*mu[i][2]+pidotr*mu[j][2]-presf*delz); + + forcecoulx += 3.0 * r5inv * ( aforcecoulx + bforcecoulx ); + forcecouly += 3.0 * r5inv * ( aforcecouly + bforcecouly ); + forcecoulz += 3.0 * r5inv * ( aforcecoulz + bforcecoulz ); + + pre2 = 3.0 * bfac * r5inv * pjdotr; + pre3 = 3.0 * bfac * r5inv * pidotr; + pre4 = -bfac * r3inv; + + crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]); + crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]); + crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]); + + tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely); + tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz); + tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx); + tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely); + tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz); + tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx); + } + + if (mu[i][3] > 0.0 && q[j] != 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz; + rcutcoul2inv=1.0/cut_coulsq[itype][jtype]; + pre1 = 3.0 * q[j] * r5inv * pidotr * (1-rsq*rcutcoul2inv); + pqfac = 1.0 - 3.0*rsq*rcutcoul2inv + + 2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv); + pre2 = q[j] * r3inv * pqfac; + + forcecoulx += pre2*mu[i][0] - pre1*delx; + forcecouly += pre2*mu[i][1] - pre1*dely; + forcecoulz += pre2*mu[i][2] - pre1*delz; + tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely); + tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz); + tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx); + } + + if (mu[j][3] > 0.0 && qtmp != 0.0) { + r3inv = r2inv*rinv; + r5inv = r3inv*r2inv; + pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz; + rcutcoul2inv=1.0/cut_coulsq[itype][jtype]; + pre1 = 3.0 * qtmp * r5inv * pjdotr * (1-rsq*rcutcoul2inv); + qpfac = 1.0 - 3.0*rsq*rcutcoul2inv + + 2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv); + pre2 = qtmp * r3inv * qpfac; + + forcecoulx += pre1*delx - pre2*mu[j][0]; + forcecouly += pre1*dely - pre2*mu[j][1]; + forcecoulz += pre1*delz - pre2*mu[j][2]; + tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely); + tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz); + tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx); + } + } + + // LJ interaction + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forceljcut = r6inv*(lj1[itype][jtype]*r6inv-lj2[itype][jtype])*r2inv; + + rcutlj2inv = 1.0 / cut_ljsq[itype][jtype]; + rcutlj6inv = rcutlj2inv * rcutlj2inv * rcutlj2inv; + forceljsf = (lj1[itype][jtype]*rcutlj6inv - lj2[itype][jtype]) * + rcutlj6inv * rcutlj2inv; + + forcelj = factor_lj * (forceljcut - forceljsf); + } else forcelj = 0.0; + + // total force + + fq = factor_coul*qqrd2e; + fx = fq*forcecoulx + delx*forcelj; + fy = fq*forcecouly + dely*forcelj; + fz = fq*forcecoulz + delz*forcelj; + + // force & torque accumulation + + fxtmp += fx; + fytmp += fy; + fztmp += fz; + t1tmp += fq*tixcoul; + t2tmp += fq*tiycoul; + t3tmp += fq*tizcoul; + + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + torque[j][0] += fq*tjxcoul; + torque[j][1] += fq*tjycoul; + torque[j][2] += fq*tjzcoul; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) { + ecoul = qtmp * q[j] * rinv * + pow((1.0-sqrt(rsq)/sqrt(cut_coulsq[itype][jtype])),2); + if (mu[i][3] > 0.0 && mu[j][3] > 0.0) + ecoul += bfac * (r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr); + if (mu[i][3] > 0.0 && q[j] != 0.0) + ecoul += -q[j] * r3inv * pqfac * pidotr; + if (mu[j][3] > 0.0 && qtmp != 0.0) + ecoul += qtmp * r3inv * qpfac * pjdotr; + ecoul *= factor_coul*qqrd2e; + } else ecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])+ + rcutlj6inv*(6*lj3[itype][jtype]*rcutlj6inv-3*lj4[itype][jtype])* + rsq*rcutlj2inv+ + rcutlj6inv*(-7*lj3[itype][jtype]*rcutlj6inv+4*lj4[itype][jtype]); + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + torque[i][0] += t1tmp; + torque[i][1] += t2tmp; + torque[i][2] += t3tmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairDipoleSFOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairDipoleSF::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_dipole_sf_omp.h b/src/USER-OMP/pair_dipole_sf_omp.h new file mode 100644 index 0000000000..e601e2d569 --- /dev/null +++ b/src/USER-OMP/pair_dipole_sf_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dipole/sf/omp,PairDipoleSFOMP) + +#else + +#ifndef LMP_PAIR_DIPOLE_SF_OMP_H +#define LMP_PAIR_DIPOLE_SF_OMP_H + +#include "pair_dipole_sf.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairDipoleSFOMP : public PairDipoleSF, public ThrOMP { + + public: + PairDipoleSFOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_dpd_omp.cpp b/src/USER-OMP/pair_dpd_omp.cpp new file mode 100644 index 0000000000..be1e32f37d --- /dev/null +++ b/src/USER-OMP/pair_dpd_omp.cpp @@ -0,0 +1,212 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_dpd_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "update.h" +#include "random_mars.h" + +using namespace LAMMPS_NS; + +#define EPSILON 1.0e-10 + +/* ---------------------------------------------------------------------- */ + +PairDPDOMP::PairDPDOMP(LAMMPS *lmp) : + PairDPD(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + random_thr = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairDPDOMP::~PairDPDOMP() +{ + if (random_thr) { + for (int i=1; i < comm->nthreads; ++i) + delete random_thr[i]; + + delete[] random_thr; + random_thr = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairDPDOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + if (!random_thr) + random_thr = new RanMars*[nthreads]; + + random_thr[0] = random; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (random_thr && tid > 0) + random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me + + comm->nprocs*tid); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairDPDOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double rsq,r,rinv,dot,wd,randnum,factor_dpd; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + double **v = atom->v; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double dtinvsqrt = 1.0/sqrt(update->dt); + double fxtmp,fytmp,fztmp; + RanMars &rng = *random_thr[tid]; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + rinv = 1.0/r; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx*delvx + dely*delvy + delz*delvz; + wd = 1.0 - r/cut[itype][jtype]; + randnum = rng.gaussian(); + + // conservative force = a0 * wd + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + + fpair = a0[itype][jtype]*wd; + fpair -= gamma[itype][jtype]*wd*wd*dot*rinv; + fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt; + fpair *= factor_dpd*rinv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wd*wd; + evdwl *= factor_dpd; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairDPDOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairDPD::memory_usage(); + bytes += comm->nthreads * sizeof(RanMars*); + bytes += comm->nthreads * sizeof(RanMars); + + return bytes; +} diff --git a/src/USER-OMP/pair_dpd_omp.h b/src/USER-OMP/pair_dpd_omp.h new file mode 100644 index 0000000000..9385e5444f --- /dev/null +++ b/src/USER-OMP/pair_dpd_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dpd/omp,PairDPDOMP) + +#else + +#ifndef LMP_PAIR_DPD_OMP_H +#define LMP_PAIR_DPD_OMP_H + +#include "pair_dpd.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairDPDOMP : public PairDPD, public ThrOMP { + + public: + PairDPDOMP(class LAMMPS *); + virtual ~PairDPDOMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + class RanMars **random_thr; + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_dpd_tstat_omp.cpp b/src/USER-OMP/pair_dpd_tstat_omp.cpp new file mode 100644 index 0000000000..7e3fb8b398 --- /dev/null +++ b/src/USER-OMP/pair_dpd_tstat_omp.cpp @@ -0,0 +1,214 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_dpd_tstat_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "update.h" +#include "random_mars.h" + +using namespace LAMMPS_NS; + +#define EPSILON 1.0e-10 + +/* ---------------------------------------------------------------------- */ + +PairDPDTstatOMP::PairDPDTstatOMP(LAMMPS *lmp) : + PairDPDTstat(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + random_thr = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairDPDTstatOMP::~PairDPDTstatOMP() +{ + if (random_thr) { + for (int i=1; i < comm->nthreads; ++i) + delete random_thr[i]; + + delete[] random_thr; + random_thr = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairDPDTstatOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + if (!random_thr) + random_thr = new RanMars*[nthreads]; + + random_thr[0] = random; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (random_thr && tid > 0) + random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me + + comm->nprocs*tid); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairDPDTstatOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double rsq,r,rinv,dot,wd,randnum,factor_dpd; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + double **v = atom->v; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double dtinvsqrt = 1.0/sqrt(update->dt); + double fxtmp,fytmp,fztmp; + RanMars &rng = *random_thr[tid]; + + // adjust sigma if target T is changing + + if (t_start != t_stop) { + double delta = update->ntimestep - update->beginstep; + delta /= update->endstep - update->beginstep; + temperature = t_start + delta * (t_stop-t_start); + double boltz = force->boltz; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) + sigma[i][j] = sigma[j][i] = sqrt(2.0*boltz*temperature*gamma[i][j]); + } + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + rinv = 1.0/r; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx*delvx + dely*delvy + delz*delvz; + wd = 1.0 - r/cut[itype][jtype]; + randnum = rng.gaussian(); + + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + + fpair = -gamma[itype][jtype]*wd*wd*dot*rinv; + fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt; + fpair *= factor_dpd*rinv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + 0.0,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairDPDTstatOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairDPDTstat::memory_usage(); + bytes += comm->nthreads * sizeof(RanMars*); + bytes += comm->nthreads * sizeof(RanMars); + + return bytes; +} diff --git a/src/USER-OMP/pair_dpd_tstat_omp.h b/src/USER-OMP/pair_dpd_tstat_omp.h new file mode 100644 index 0000000000..14f640a925 --- /dev/null +++ b/src/USER-OMP/pair_dpd_tstat_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dpd/tstat/omp,PairDPDTstatOMP) + +#else + +#ifndef LMP_PAIR_DPD_TSTAT_OMP_H +#define LMP_PAIR_DPD_TSTAT_OMP_H + +#include "pair_dpd_tstat.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairDPDTstatOMP : public PairDPDTstat, public ThrOMP { + + public: + PairDPDTstatOMP(class LAMMPS *); + virtual ~PairDPDTstatOMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + class RanMars **random_thr; + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_eam_alloy_omp.cpp b/src/USER-OMP/pair_eam_alloy_omp.cpp new file mode 100644 index 0000000000..54be571b7f --- /dev/null +++ b/src/USER-OMP/pair_eam_alloy_omp.cpp @@ -0,0 +1,323 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Stephen Foiles (SNL), Murray Daw (SNL) +------------------------------------------------------------------------- */ + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_eam_alloy_omp.h" +#include "atom.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +PairEAMAlloyOMP::PairEAMAlloyOMP(LAMMPS *lmp) : PairEAMOMP(lmp) +{ + one_coeff = 1; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + read DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMAlloyOMP::coeff(int narg, char **arg) +{ + int i,j; + + if (!allocated) allocate(); + + if (narg != 3 + atom->ntypes) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // insure I,J args are * * + + if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // read EAM setfl file + + if (setfl) { + for (i = 0; i < setfl->nelements; i++) delete [] setfl->elements[i]; + delete [] setfl->elements; + delete [] setfl->mass; + memory->destroy(setfl->frho); + memory->destroy(setfl->rhor); + memory->destroy(setfl->z2r); + delete setfl; + } + setfl = new Setfl(); + read_file(arg[2]); + + // read args that map atom types to elements in potential file + // map[i] = which element the Ith atom type is, -1 if NULL + + for (i = 3; i < narg; i++) { + if (strcmp(arg[i],"NULL") == 0) { + map[i-2] = -1; + continue; + } + for (j = 0; j < setfl->nelements; j++) + if (strcmp(arg[i],setfl->elements[j]) == 0) break; + if (j < setfl->nelements) map[i-2] = j; + else error->all(FLERR,"No matching element in EAM potential file"); + } + + // clear setflag since coeff() called once with I,J = * * + + int n = atom->ntypes; + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + // set setflag i,j for type pairs where both are mapped to elements + // set mass of atom type if i = j + + int count = 0; + for (i = 1; i <= n; i++) { + for (j = i; j <= n; j++) { + if (map[i] >= 0 && map[j] >= 0) { + setflag[i][j] = 1; + if (i == j) atom->set_mass(i,setfl->mass[map[i]]); + count++; + } + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + read a multi-element DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMAlloyOMP::read_file(char *filename) +{ + Setfl *file = setfl; + + // open potential file + + int me = comm->me; + FILE *fptr; + char line[MAXLINE]; + + if (me == 0) { + fptr = fopen(filename,"r"); + if (fptr == NULL) { + char str[128]; + sprintf(str,"Cannot open EAM potential file %s",filename); + error->one(FLERR,str); + } + } + + // read and broadcast header + // extract element names from nelements line + + int n; + if (me == 0) { + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + n = strlen(line) + 1; + } + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + sscanf(line,"%d",&file->nelements); + int nwords = atom->count_words(line); + if (nwords != file->nelements + 1) + error->all(FLERR,"Incorrect element names in EAM potential file"); + + char **words = new char*[file->nelements+1]; + nwords = 0; + strtok(line," \t\n\r\f"); + while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue; + + file->elements = new char*[file->nelements]; + for (int i = 0; i < file->nelements; i++) { + n = strlen(words[i]) + 1; + file->elements[i] = new char[n]; + strcpy(file->elements[i],words[i]); + } + delete [] words; + + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg %d %lg %lg", + &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut); + } + + MPI_Bcast(&file->nrho,1,MPI_INT,0,world); + MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->nr,1,MPI_INT,0,world); + MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world); + + file->mass = new double[file->nelements]; + memory->create(file->frho,file->nelements,file->nrho+1,"pair:frho"); + memory->create(file->rhor,file->nelements,file->nr+1,"pair:rhor"); + memory->create(file->z2r,file->nelements,file->nelements,file->nr+1, + "pair:z2r"); + + int i,j,tmp; + for (i = 0; i < file->nelements; i++) { + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg",&tmp,&file->mass[i]); + } + MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world); + + if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]); + MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world); + if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]); + MPI_Bcast(&file->rhor[i][1],file->nr,MPI_DOUBLE,0,world); + } + + for (i = 0; i < file->nelements; i++) + for (j = 0; j <= i; j++) { + if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]); + MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + + // close the potential file + + if (me == 0) fclose(fptr); +} + +/* ---------------------------------------------------------------------- + copy read-in setfl potential to standard array format +------------------------------------------------------------------------- */ + +void PairEAMAlloyOMP::file2array() +{ + int i,j,m,n; + int ntypes = atom->ntypes; + + // set function params directly from setfl file + + nrho = setfl->nrho; + nr = setfl->nr; + drho = setfl->drho; + dr = setfl->dr; + + // ------------------------------------------------------------------ + // setup frho arrays + // ------------------------------------------------------------------ + + // allocate frho arrays + // nfrho = # of setfl elements + 1 for zero array + + nfrho = setfl->nelements + 1; + memory->destroy(frho); + memory->create(frho,nfrho,nrho+1,"pair:frho"); + + // copy each element's frho to global frho + + for (i = 0; i < setfl->nelements; i++) + for (m = 1; m <= nrho; m++) frho[i][m] = setfl->frho[i][m]; + + // add extra frho of zeroes for non-EAM types to point to (pair hybrid) + // this is necessary b/c fp is still computed for non-EAM atoms + + for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0; + + // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to + // if atom type doesn't point to element (non-EAM atom in pair hybrid) + // then map it to last frho array of zeroes + + for (i = 1; i <= ntypes; i++) + if (map[i] >= 0) type2frho[i] = map[i]; + else type2frho[i] = nfrho-1; + + // ------------------------------------------------------------------ + // setup rhor arrays + // ------------------------------------------------------------------ + + // allocate rhor arrays + // nrhor = # of setfl elements + + nrhor = setfl->nelements; + memory->destroy(rhor); + memory->create(rhor,nrhor,nr+1,"pair:rhor"); + + // copy each element's rhor to global rhor + + for (i = 0; i < setfl->nelements; i++) + for (m = 1; m <= nr; m++) rhor[i][m] = setfl->rhor[i][m]; + + // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to + // for setfl files, I,J mapping only depends on I + // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used + + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + type2rhor[i][j] = map[i]; + + // ------------------------------------------------------------------ + // setup z2r arrays + // ------------------------------------------------------------------ + + // allocate z2r arrays + // nz2r = N*(N+1)/2 where N = # of setfl elements + + nz2r = setfl->nelements * (setfl->nelements+1) / 2; + memory->destroy(z2r); + memory->create(z2r,nz2r,nr+1,"pair:z2r"); + + // copy each element pair z2r to global z2r, only for I >= J + + n = 0; + for (i = 0; i < setfl->nelements; i++) + for (j = 0; j <= i; j++) { + for (m = 1; m <= nr; m++) z2r[n][m] = setfl->z2r[i][j][m]; + n++; + } + + // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to + // set of z2r arrays only fill lower triangular Nelement matrix + // value = n = sum over rows of lower-triangular matrix until reach irow,icol + // swap indices when irow < icol to stay lower triangular + // if map = -1 (non-EAM atom in pair hybrid): + // type2z2r is not used by non-opt + // but set type2z2r to 0 since accessed by opt + + int irow,icol; + for (i = 1; i <= ntypes; i++) { + for (j = 1; j <= ntypes; j++) { + irow = map[i]; + icol = map[j]; + if (irow == -1 || icol == -1) { + type2z2r[i][j] = 0; + continue; + } + if (irow < icol) { + irow = map[j]; + icol = map[i]; + } + n = 0; + for (m = 0; m < irow; m++) n += m + 1; + n += icol; + type2z2r[i][j] = n; + } + } +} diff --git a/src/USER-OMP/pair_eam_alloy_omp.h b/src/USER-OMP/pair_eam_alloy_omp.h new file mode 100644 index 0000000000..7a71fbc17a --- /dev/null +++ b/src/USER-OMP/pair_eam_alloy_omp.h @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/alloy/omp,PairEAMAlloyOMP) + +#else + +#ifndef LMP_PAIR_EAM_ALLOY_OMP_H +#define LMP_PAIR_EAM_ALLOY_OMP_H + +#include "pair_eam_omp.h" + +namespace LAMMPS_NS { + +// need virtual public b/c of how eam/alloy/opt inherits from it + +class PairEAMAlloyOMP : virtual public PairEAMOMP { + public: + PairEAMAlloyOMP(class LAMMPS *); + virtual ~PairEAMAlloyOMP() {} + void coeff(int, char **); + + protected: + void read_file(char *); + void file2array(); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_eam_fs_omp.cpp b/src/USER-OMP/pair_eam_fs_omp.cpp new file mode 100644 index 0000000000..d0963fa621 --- /dev/null +++ b/src/USER-OMP/pair_eam_fs_omp.cpp @@ -0,0 +1,332 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Tim Lau (MIT) +------------------------------------------------------------------------- */ + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_eam_fs_omp.h" +#include "atom.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +PairEAMFSOMP::PairEAMFSOMP(LAMMPS *lmp) : PairEAMOMP(lmp) +{ + one_coeff = 1; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + read EAM Finnis-Sinclair file +------------------------------------------------------------------------- */ + +void PairEAMFSOMP::coeff(int narg, char **arg) +{ + int i,j; + + if (!allocated) allocate(); + + if (narg != 3 + atom->ntypes) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // insure I,J args are * * + + if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // read EAM Finnis-Sinclair file + + if (fs) { + for (i = 0; i < fs->nelements; i++) delete [] fs->elements[i]; + delete [] fs->elements; + delete [] fs->mass; + memory->destroy(fs->frho); + memory->destroy(fs->rhor); + memory->destroy(fs->z2r); + delete fs; + } + fs = new Fs(); + read_file(arg[2]); + + // read args that map atom types to elements in potential file + // map[i] = which element the Ith atom type is, -1 if NULL + + for (i = 3; i < narg; i++) { + if (strcmp(arg[i],"NULL") == 0) { + map[i-2] = -1; + continue; + } + for (j = 0; j < fs->nelements; j++) + if (strcmp(arg[i],fs->elements[j]) == 0) break; + if (j < fs->nelements) map[i-2] = j; + else error->all(FLERR,"No matching element in EAM potential file"); + } + + // clear setflag since coeff() called once with I,J = * * + + int n = atom->ntypes; + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + // set setflag i,j for type pairs where both are mapped to elements + // set mass of atom type if i = j + + int count = 0; + for (i = 1; i <= n; i++) { + for (j = i; j <= n; j++) { + if (map[i] >= 0 && map[j] >= 0) { + setflag[i][j] = 1; + if (i == j) atom->set_mass(i,fs->mass[map[i]]); + count++; + } + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + read a multi-element DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMFSOMP::read_file(char *filename) +{ + Fs *file = fs; + + // open potential file + + int me = comm->me; + FILE *fptr; + char line[MAXLINE]; + + if (me == 0) { + fptr = fopen(filename,"r"); + if (fptr == NULL) { + char str[128]; + sprintf(str,"Cannot open EAM potential file %s",filename); + error->one(FLERR,str); + } + } + + // read and broadcast header + // extract element names from nelements line + + int n; + if (me == 0) { + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + n = strlen(line) + 1; + } + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + sscanf(line,"%d",&file->nelements); + int nwords = atom->count_words(line); + if (nwords != file->nelements + 1) + error->all(FLERR,"Incorrect element names in EAM potential file"); + + char **words = new char*[file->nelements+1]; + nwords = 0; + strtok(line," \t\n\r\f"); + while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue; + + file->elements = new char*[file->nelements]; + for (int i = 0; i < file->nelements; i++) { + n = strlen(words[i]) + 1; + file->elements[i] = new char[n]; + strcpy(file->elements[i],words[i]); + } + delete [] words; + + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg %d %lg %lg", + &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut); + } + + MPI_Bcast(&file->nrho,1,MPI_INT,0,world); + MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->nr,1,MPI_INT,0,world); + MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world); + + file->mass = new double[file->nelements]; + memory->create(file->frho,file->nelements,file->nrho+1, + "pair:frho"); + memory->create(file->rhor,file->nelements,file->nelements, + file->nr+1,"pair:rhor"); + memory->create(file->z2r,file->nelements,file->nelements, + file->nr+1,"pair:z2r"); + + int i,j,tmp; + for (i = 0; i < file->nelements; i++) { + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg",&tmp,&file->mass[i]); + } + MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world); + + if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]); + MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world); + + for (j = 0; j < file->nelements; j++) { + if (me == 0) grab(fptr,file->nr,&file->rhor[i][j][1]); + MPI_Bcast(&file->rhor[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + } + + for (i = 0; i < file->nelements; i++) + for (j = 0; j <= i; j++) { + if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]); + MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + + // close the potential file + + if (me == 0) fclose(fptr); +} + +/* ---------------------------------------------------------------------- + copy read-in setfl potential to standard array format +------------------------------------------------------------------------- */ + +void PairEAMFSOMP::file2array() +{ + int i,j,m,n; + int ntypes = atom->ntypes; + + // set function params directly from fs file + + nrho = fs->nrho; + nr = fs->nr; + drho = fs->drho; + dr = fs->dr; + + // ------------------------------------------------------------------ + // setup frho arrays + // ------------------------------------------------------------------ + + // allocate frho arrays + // nfrho = # of fs elements + 1 for zero array + + nfrho = fs->nelements + 1; + memory->destroy(frho); + memory->create(frho,nfrho,nrho+1,"pair:frho"); + + // copy each element's frho to global frho + + for (i = 0; i < fs->nelements; i++) + for (m = 1; m <= nrho; m++) frho[i][m] = fs->frho[i][m]; + + // add extra frho of zeroes for non-EAM types to point to (pair hybrid) + // this is necessary b/c fp is still computed for non-EAM atoms + + for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0; + + // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to + // if atom type doesn't point to element (non-EAM atom in pair hybrid) + // then map it to last frho array of zeroes + + for (i = 1; i <= ntypes; i++) + if (map[i] >= 0) type2frho[i] = map[i]; + else type2frho[i] = nfrho-1; + + // ------------------------------------------------------------------ + // setup rhor arrays + // ------------------------------------------------------------------ + + // allocate rhor arrays + // nrhor = square of # of fs elements + + nrhor = fs->nelements * fs->nelements; + memory->destroy(rhor); + memory->create(rhor,nrhor,nr+1,"pair:rhor"); + + // copy each element pair rhor to global rhor + + n = 0; + for (i = 0; i < fs->nelements; i++) + for (j = 0; j < fs->nelements; j++) { + for (m = 1; m <= nr; m++) rhor[n][m] = fs->rhor[i][j][m]; + n++; + } + + // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to + // for fs files, there is a full NxN set of rhor arrays + // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used + + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + type2rhor[i][j] = map[i] * fs->nelements + map[j]; + + // ------------------------------------------------------------------ + // setup z2r arrays + // ------------------------------------------------------------------ + + // allocate z2r arrays + // nz2r = N*(N+1)/2 where N = # of fs elements + + nz2r = fs->nelements * (fs->nelements+1) / 2; + memory->destroy(z2r); + memory->create(z2r,nz2r,nr+1,"pair:z2r"); + + // copy each element pair z2r to global z2r, only for I >= J + + n = 0; + for (i = 0; i < fs->nelements; i++) + for (j = 0; j <= i; j++) { + for (m = 1; m <= nr; m++) z2r[n][m] = fs->z2r[i][j][m]; + n++; + } + + // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to + // set of z2r arrays only fill lower triangular Nelement matrix + // value = n = sum over rows of lower-triangular matrix until reach irow,icol + // swap indices when irow < icol to stay lower triangular + // if map = -1 (non-EAM atom in pair hybrid): + // type2z2r is not used by non-opt + // but set type2z2r to 0 since accessed by opt + + int irow,icol; + for (i = 1; i <= ntypes; i++) { + for (j = 1; j <= ntypes; j++) { + irow = map[i]; + icol = map[j]; + if (irow == -1 || icol == -1) { + type2z2r[i][j] = 0; + continue; + } + if (irow < icol) { + irow = map[j]; + icol = map[i]; + } + n = 0; + for (m = 0; m < irow; m++) n += m + 1; + n += icol; + type2z2r[i][j] = n; + } + } +} diff --git a/src/USER-OMP/pair_eam_fs_omp.h b/src/USER-OMP/pair_eam_fs_omp.h new file mode 100644 index 0000000000..bee6cef762 --- /dev/null +++ b/src/USER-OMP/pair_eam_fs_omp.h @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/fs/omp,PairEAMFSOMP) + +#else + +#ifndef LMP_PAIR_EAM_FS_OMP_H +#define LMP_PAIR_EAM_FS_OMP_H + +#include "pair_eam_omp.h" + +namespace LAMMPS_NS { + +// need virtual public b/c of how eam/fs/opt inherits from it + +class PairEAMFSOMP : virtual public PairEAMOMP { + public: + PairEAMFSOMP(class LAMMPS *); + virtual ~PairEAMFSOMP() {} + void coeff(int, char **); + + protected: + void read_file(char *); + void file2array(); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_eam_omp.cpp b/src/USER-OMP/pair_eam_omp.cpp new file mode 100644 index 0000000000..0ae4d54fb7 --- /dev/null +++ b/src/USER-OMP/pair_eam_omp.cpp @@ -0,0 +1,303 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" + +#include "pair_eam_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairEAMOMP::PairEAMOMP(LAMMPS *lmp) : + PairEAM(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairEAMOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow energy and fp arrays if necessary + // need to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(rho); + memory->destroy(fp); + nmax = atom->nmax; + memory->create(rho,nthreads*nmax,"pair:rho"); + memory->create(fp,nmax,"pair:fp"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, *rho_t; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + if (force->newton_pair) + rho_t = rho + tid*nall; + else rho_t = rho + tid*atom->nlocal; + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, rho_t, ifrom, ito, tid); + else eval<1,1,0>(f, rho_t, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, rho_t, ifrom, ito, tid); + else eval<1,0,0>(f, rho_t, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, rho_t, ifrom, ito, tid); + else eval<0,0,0>(f, rho_t, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairEAMOMP::eval(double **f, double *rho_t, + int iifrom, int iito, int tid) +{ + int i,j,ii,jj,m,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi; + double *coeff; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // zero out density + + if (NEWTON_PAIR) memset(rho_t, 0, nall*sizeof(double)); + else memset(rho_t, 0, nlocal*sizeof(double)); + + // rho = density at each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + 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]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + jtype = type[j]; + p = sqrt(rsq)*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + coeff = rhor_spline[type2rhor[jtype][itype]][m]; + rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + if (NEWTON_PAIR || j < nlocal) { + coeff = rhor_spline[type2rhor[itype][jtype]][m]; + rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + } + } + } + } + + // wait until all threads are done with computation + sync_threads(); + + // communicate and sum densities + + if (NEWTON_PAIR) { + // reduce per thread density + data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { comm->reverse_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + } else { + data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + } + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + p = rho[i]*rdrho + 1.0; + m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + coeff = frho_spline[type2frho[type[i]]][m]; + fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; + if (EFLAG) { + phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + if (eflag_global) eng_vdwl_thr[tid] += phi; + if (eflag_atom) eatom_thr[tid][i] += phi; + } + } + + // wait until all theads are done with computation + sync_threads(); + + // communicate derivative of embedding function + // MPI communication only on master thread +#if defined(_OPENMP) +#pragma omp master +#endif + { comm->forward_comm_pair(this); } + + // wait until master thread is done with communication + sync_threads(); + + // compute forces on each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + fxtmp = fytmp = fztmp = 0.0; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + jtype = type[j]; + r = sqrt(rsq); + p = r*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + coeff = rhor_spline[type2rhor[itype][jtype]][m]; + rhoip = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = rhor_spline[type2rhor[jtype][itype]][m]; + rhojp = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = z2r_spline[type2z2r[itype][jtype]][m]; + z2p = (coeff[0]*p + coeff[1])*p + coeff[2]; + z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + + recip = 1.0/r; + phi = z2*recip; + phip = z2p*recip - phi*recip; + psip = fp[i]*rhojp + fp[j]*rhoip + phip; + fpair = -psip*recip; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) evdwl = phi; + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairEAMOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairEAM::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_eam_omp.h b/src/USER-OMP/pair_eam_omp.h new file mode 100644 index 0000000000..1184cb34bc --- /dev/null +++ b/src/USER-OMP/pair_eam_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/omp,PairEAMOMP) + +#else + +#ifndef LMP_PAIR_EAM_OMP_H +#define LMP_PAIR_EAM_OMP_H + +#include "pair_eam.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairEAMOMP : public PairEAM, public ThrOMP { + + public: + PairEAMOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double *rho_t, int iifrom, int iito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_edip_omp.cpp b/src/USER-OMP/pair_edip_omp.cpp new file mode 100644 index 0000000000..65b05c8143 --- /dev/null +++ b/src/USER-OMP/pair_edip_omp.cpp @@ -0,0 +1,485 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_edip_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairEDIPOMP::PairEDIPOMP(LAMMPS *lmp) : + PairEDIP(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIPOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = vflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else eval<0,0,0>(f, ifrom, ito, tid); + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairEDIPOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,ii,inum,jnum; + int itype,jtype,ktype,ijparam,ikparam,ijkparam; + double xtmp,ytmp,ztmp,evdwl; + int *ilist,*jlist,*numneigh,**firstneigh; + register int preForceCoord_counter; + + double invR_ij; + double invR_ik; + double directorCos_ij_x; + double directorCos_ij_y; + double directorCos_ij_z; + double directorCos_ik_x; + double directorCos_ik_y; + double directorCos_ik_z; + double cosTeta; + + int interpolIDX; + double interpolTMP; + double interpolDeltaX; + double interpolY1; + double interpolY2; + + double invRMinusCutoffA; + double sigmaInvRMinusCutoffA; + double gammInvRMinusCutoffA; + double cosTetaDiff; + double cosTetaDiffCosTetaDiff; + double cutoffFunction_ij; + double exp2B_ij; + double exp2BDerived_ij; + double pow2B_ij; + double pow2BDerived_ij; + double exp3B_ij; + double exp3BDerived_ij; + double exp3B_ik; + double exp3BDerived_ik; + double qFunction; + double qFunctionDerived; + double tauFunction; + double tauFunctionDerived; + double expMinusBetaZeta_iZeta_i; + double qFunctionCosTetaDiffCosTetaDiff; + double expMinusQFunctionCosTetaDiffCosTetaDiff; + double zeta_i; + double zeta_iDerived; + double zeta_iDerivedInvR_ij; + + double forceModCoord_factor; + double forceModCoord; + double forceModCoord_ij; + double forceMod2B; + double forceMod3B_factor1_ij; + double forceMod3B_factor2_ij; + double forceMod3B_factor2; + double forceMod3B_factor1_ik; + double forceMod3B_factor2_ik; + double potentia3B_factor; + double potential2B_factor; + + double *pre_thrInvR_ij = preInvR_ij + tid * leadDimInteractionList; + double *pre_thrExp3B_ij = preExp3B_ij + tid * leadDimInteractionList; + double *pre_thrExp3BDerived_ij = preExp3BDerived_ij + tid * leadDimInteractionList; + double *pre_thrExp2B_ij = preExp2B_ij + tid * leadDimInteractionList; + double *pre_thrExp2BDerived_ij = preExp2BDerived_ij + tid * leadDimInteractionList; + double *pre_thrPow2B_ij = prePow2B_ij + tid * leadDimInteractionList; + double *pre_thrForceCoord = preForceCoord + tid * leadDimInteractionList; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over full neighbor list of my atoms + + for (ii = iifrom; ii < iito; ii++) { + zeta_i = 0.0; + int numForceCoordPairs = 0; + + i = ilist[ii]; + itype = map[type[i]]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + // pre-loop to compute environment coordination f(Z) + + for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) { + j = jlist[neighbor_j]; + j &= NEIGHMASK; + + double dr_ij[3], r_ij; + + dr_ij[0] = xtmp - x[j][0]; + dr_ij[1] = ytmp - x[j][1]; + dr_ij[2] = ztmp - x[j][2]; + r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2]; + + jtype = map[type[j]]; + ijparam = elem2param[itype][jtype][jtype]; + if (r_ij > params[ijparam].cutsq) continue; + + r_ij = sqrt(r_ij); + + invR_ij = 1.0 / r_ij; + pre_thrInvR_ij[neighbor_j] = invR_ij; + + invRMinusCutoffA = 1.0 / (r_ij - cutoffA); + sigmaInvRMinusCutoffA = sigma * invRMinusCutoffA; + gammInvRMinusCutoffA = gamm * invRMinusCutoffA; + + interpolDeltaX = r_ij - GRIDSTART; + interpolTMP = (interpolDeltaX * GRIDDENSITY); + interpolIDX = (int) interpolTMP; + + interpolY1 = exp3B[interpolIDX]; + interpolY2 = exp3B[interpolIDX+1]; + exp3B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + exp3BDerived_ij = - exp3B_ij * gammInvRMinusCutoffA * invRMinusCutoffA; + + pre_thrExp3B_ij[neighbor_j] = exp3B_ij; + pre_thrExp3BDerived_ij[neighbor_j] = exp3BDerived_ij; + + interpolY1 = exp2B[interpolIDX]; + interpolY2 = exp2B[interpolIDX+1]; + exp2B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + exp2BDerived_ij = - exp2B_ij * sigmaInvRMinusCutoffA * invRMinusCutoffA; + + pre_thrExp2B_ij[neighbor_j] = exp2B_ij; + pre_thrExp2BDerived_ij[neighbor_j] = exp2BDerived_ij; + + interpolY1 = pow2B[interpolIDX]; + interpolY2 = pow2B[interpolIDX+1]; + pow2B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + pre_thrPow2B_ij[neighbor_j] = pow2B_ij; + + // zeta and its derivative + + if (r_ij < cutoffC) zeta_i += 1.0; + else { + interpolY1 = cutoffFunction[interpolIDX]; + interpolY2 = cutoffFunction[interpolIDX+1]; + cutoffFunction_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + zeta_i += cutoffFunction_ij; + + interpolY1 = cutoffFunctionDerived[interpolIDX]; + interpolY2 = cutoffFunctionDerived[interpolIDX+1]; + zeta_iDerived = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + zeta_iDerivedInvR_ij = zeta_iDerived * invR_ij; + + preForceCoord_counter=numForceCoordPairs*5; + pre_thrForceCoord[preForceCoord_counter+0]=zeta_iDerivedInvR_ij; + pre_thrForceCoord[preForceCoord_counter+1]=dr_ij[0]; + pre_thrForceCoord[preForceCoord_counter+2]=dr_ij[1]; + pre_thrForceCoord[preForceCoord_counter+3]=dr_ij[2]; + pre_thrForceCoord[preForceCoord_counter+4]=j; + numForceCoordPairs++; + } + } + + // quantities depending on zeta_i + + interpolDeltaX = zeta_i; + interpolTMP = (interpolDeltaX * GRIDDENSITY); + interpolIDX = (int) interpolTMP; + + interpolY1 = expMinusBetaZeta_iZeta_iGrid[interpolIDX]; + interpolY2 = expMinusBetaZeta_iZeta_iGrid[interpolIDX+1]; + expMinusBetaZeta_iZeta_i = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = qFunctionGrid[interpolIDX]; + interpolY2 = qFunctionGrid[interpolIDX+1]; + qFunction = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = tauFunctionGrid[interpolIDX]; + interpolY2 = tauFunctionGrid[interpolIDX+1]; + tauFunction = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = tauFunctionDerivedGrid[interpolIDX]; + interpolY2 = tauFunctionDerivedGrid[interpolIDX+1]; + tauFunctionDerived = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + qFunctionDerived = -mu * qFunction; + + forceModCoord_factor = 2.0 * beta * zeta_i * expMinusBetaZeta_iZeta_i; + + forceModCoord = 0.0; + + // two-body interactions, skip half of them + + for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) { + double dr_ij[3], r_ij, f_ij[3]; + + j = jlist[neighbor_j]; + j &= NEIGHMASK; + + dr_ij[0] = x[j][0] - xtmp; + dr_ij[1] = x[j][1] - ytmp; + dr_ij[2] = x[j][2] - ztmp; + r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2]; + + jtype = map[type[j]]; + ijparam = elem2param[itype][jtype][jtype]; + if (r_ij > params[ijparam].cutsq) continue; + + r_ij = sqrt(r_ij); + + invR_ij = pre_thrInvR_ij[neighbor_j]; + pow2B_ij = pre_thrPow2B_ij[neighbor_j]; + + potential2B_factor = pow2B_ij - expMinusBetaZeta_iZeta_i; + + exp2B_ij = pre_thrExp2B_ij[neighbor_j]; + + pow2BDerived_ij = - rho * invR_ij * pow2B_ij; + + forceModCoord += (forceModCoord_factor*exp2B_ij); + + exp2BDerived_ij = pre_thrExp2BDerived_ij[neighbor_j]; + forceMod2B = exp2BDerived_ij * potential2B_factor + + exp2B_ij * pow2BDerived_ij; + + directorCos_ij_x = invR_ij * dr_ij[0]; + directorCos_ij_y = invR_ij * dr_ij[1]; + directorCos_ij_z = invR_ij * dr_ij[2]; + + exp3B_ij = pre_thrExp3B_ij[neighbor_j]; + exp3BDerived_ij = pre_thrExp3BDerived_ij[neighbor_j]; + + f_ij[0] = forceMod2B * directorCos_ij_x; + f_ij[1] = forceMod2B * directorCos_ij_y; + f_ij[2] = forceMod2B * directorCos_ij_z; + + f[j][0] -= f_ij[0]; + f[j][1] -= f_ij[1]; + f[j][2] -= f_ij[2]; + + f[i][0] += f_ij[0]; + f[i][1] += f_ij[1]; + f[i][2] += f_ij[2]; + + // potential energy + + evdwl = (exp2B_ij * potential2B_factor); + + if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, evdwl, 0.0, + -forceMod2B*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid); + + // three-body Forces + + for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) { + double dr_ik[3], r_ik, f_ik[3]; + + k = jlist[neighbor_k]; + k &= NEIGHMASK; + ktype = map[type[k]]; + ikparam = elem2param[itype][ktype][ktype]; + ijkparam = elem2param[itype][jtype][ktype]; + + dr_ik[0] = x[k][0] - xtmp; + dr_ik[1] = x[k][1] - ytmp; + dr_ik[2] = x[k][2] - ztmp; + r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2]; + + if (r_ik > params[ikparam].cutsq) continue; + + r_ik = sqrt(r_ik); + + invR_ik = pre_thrInvR_ij[neighbor_k]; + + directorCos_ik_x = invR_ik * dr_ik[0]; + directorCos_ik_y = invR_ik * dr_ik[1]; + directorCos_ik_z = invR_ik * dr_ik[2]; + + cosTeta = directorCos_ij_x * directorCos_ik_x + + directorCos_ij_y * directorCos_ik_y + + directorCos_ij_z * directorCos_ik_z; + + cosTetaDiff = cosTeta + tauFunction; + cosTetaDiffCosTetaDiff = cosTetaDiff * cosTetaDiff; + qFunctionCosTetaDiffCosTetaDiff = cosTetaDiffCosTetaDiff * qFunction; + expMinusQFunctionCosTetaDiffCosTetaDiff = + exp(-qFunctionCosTetaDiffCosTetaDiff); + + potentia3B_factor = lambda * + ((1.0 - expMinusQFunctionCosTetaDiffCosTetaDiff) + + eta * qFunctionCosTetaDiffCosTetaDiff); + + exp3B_ik = pre_thrExp3B_ij[neighbor_k]; + exp3BDerived_ik = pre_thrExp3BDerived_ij[neighbor_k]; + + forceMod3B_factor1_ij = - exp3BDerived_ij * exp3B_ik * + potentia3B_factor; + forceMod3B_factor2 = 2.0 * lambda * exp3B_ij * exp3B_ik * + qFunction * cosTetaDiff * + (eta + expMinusQFunctionCosTetaDiffCosTetaDiff); + forceMod3B_factor2_ij = forceMod3B_factor2 * invR_ij; + + f_ij[0] = forceMod3B_factor1_ij * directorCos_ij_x + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_x - directorCos_ik_x); + f_ij[1] = forceMod3B_factor1_ij * directorCos_ij_y + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_y - directorCos_ik_y); + f_ij[2] = forceMod3B_factor1_ij * directorCos_ij_z + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_z - directorCos_ik_z); + + forceMod3B_factor1_ik = - exp3BDerived_ik * exp3B_ij * + potentia3B_factor; + forceMod3B_factor2_ik = forceMod3B_factor2 * invR_ik; + + f_ik[0] = forceMod3B_factor1_ik * directorCos_ik_x + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_x - directorCos_ij_x); + f_ik[1] = forceMod3B_factor1_ik * directorCos_ik_y + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_y - directorCos_ij_y); + f_ik[2] = forceMod3B_factor1_ik * directorCos_ik_z + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_z - directorCos_ij_z); + + forceModCoord += (forceMod3B_factor2 * + (tauFunctionDerived - 0.5 * mu * cosTetaDiff)); + + f[j][0] += f_ij[0]; + f[j][1] += f_ij[1]; + f[j][2] += f_ij[2]; + + f[k][0] += f_ik[0]; + f[k][1] += f_ik[1]; + f[k][2] += f_ik[2]; + + f[i][0] -= f_ij[0] + f_ik[0]; + f[i][1] -= f_ij[1] + f_ik[1]; + f[i][2] -= f_ij[2] + f_ik[2]; + + // potential energy + + evdwl = (exp3B_ij * exp3B_ik * potentia3B_factor); + + if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik); + } + } + + // forces due to environment coordination f(Z) + + for (int idx = 0; idx < numForceCoordPairs; idx++) { + double dr_ij[3], f_ij[3]; + + preForceCoord_counter = idx * 5; + zeta_iDerivedInvR_ij=pre_thrForceCoord[preForceCoord_counter+0]; + dr_ij[0]=pre_thrForceCoord[preForceCoord_counter+1]; + dr_ij[1]=pre_thrForceCoord[preForceCoord_counter+2]; + dr_ij[2]=pre_thrForceCoord[preForceCoord_counter+3]; + j = static_cast (pre_thrForceCoord[preForceCoord_counter+4]); + + forceModCoord_ij = forceModCoord * zeta_iDerivedInvR_ij; + + f_ij[0] = forceModCoord_ij * dr_ij[0]; + f_ij[1] = forceModCoord_ij * dr_ij[1]; + f_ij[2] = forceModCoord_ij * dr_ij[2]; + + f[j][0] -= f_ij[0]; + f[j][1] -= f_ij[1]; + f[j][2] -= f_ij[2]; + + f[i][0] += f_ij[0]; + f[i][1] += f_ij[1]; + f[i][2] += f_ij[2]; + + // potential energy + + evdwl = 0.0; + if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, 0.0, 0.0, + forceModCoord_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairEDIPOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairEDIP::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_edip_omp.h b/src/USER-OMP/pair_edip_omp.h new file mode 100644 index 0000000000..55c34db345 --- /dev/null +++ b/src/USER-OMP/pair_edip_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(edip/omp,PairEDIPOMP) + +#else + +#ifndef LMP_PAIR_EDIP_OMP_H +#define LMP_PAIR_EDIP_OMP_H + +#include "pair_edip.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairEDIPOMP : public PairEDIP, public ThrOMP { + + public: + PairEDIPOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_eim_omp.cpp b/src/USER-OMP/pair_eim_omp.cpp new file mode 100644 index 0000000000..d31ad20120 --- /dev/null +++ b/src/USER-OMP/pair_eim_omp.cpp @@ -0,0 +1,365 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" + +#include "pair_eim_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairEIMOMP::PairEIMOMP(LAMMPS *lmp) : + PairEIM(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairEIMOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow energy and fp arrays if necessary + // need to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(rho); + memory->destroy(fp); + nmax = atom->nmax; + memory->create(rho,nthreads*nmax,"pair:rho"); + memory->create(fp,nthreads*nmax,"pair:fp"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, *rho_t, *fp_t; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + if (force->newton_pair) { + rho_t = rho + tid*nall; + fp_t = fp + tid*nall; + } else { + rho_t = rho + tid*atom->nlocal; + fp_t = fp + tid*atom->nlocal; + } + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, rho_t, fp_t, ifrom, ito, tid); + else eval<1,1,0>(f, rho_t, fp_t, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, rho_t, fp_t, ifrom, ito, tid); + else eval<1,0,0>(f, rho_t, fp_t, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, rho_t, fp_t, ifrom, ito, tid); + else eval<0,0,0>(f, rho_t, fp_t, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairEIMOMP::eval(double **f, double *rho_t, double *fp_t, + int iifrom, int iito, int tid) +{ + int i,j,ii,jj,m,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,p,rhoip,rhojp,phip,phi,coul,coulp,recip,psip; + double *coeff; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // zero out density and fp + + if (NEWTON_PAIR) { + memset(rho_t, 0, nall*sizeof(double)); + memset(fp_t, 0, nall*sizeof(double)); + } else { + memset(rho_t, 0, nlocal*sizeof(double)); + memset(fp_t, 0, nlocal*sizeof(double)); + } + + // rho = density at each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + 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]; + j &= NEIGHMASK; + 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 < cutforcesq[itype][jtype]) { + p = sqrt(rsq)*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + coeff = Fij_spline[type2Fij[itype][jtype]][m]; + rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + if (NEWTON_PAIR || j < nlocal) { + coeff = Fij_spline[type2Fij[jtype][itype]][m]; + rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + } + } + } + } + + // wait until all threads are done with computation + sync_threads(); + + // communicate and sum densities + if (NEWTON_PAIR) { + // reduce per thread density + data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { + rhofp = 1; + comm->reverse_comm_pair(this); + } + + } else { + data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + } + +#if defined(_OPENMP) +#pragma omp master +#endif + { + rhofp = 1; + comm->forward_comm_pair(this); + } + + // wait until master is finished communicating + sync_threads(); + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + 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]; + j &= NEIGHMASK; + 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 < cutforcesq[itype][jtype]) { + p = sqrt(rsq)*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + coeff = Gij_spline[type2Gij[itype][jtype]][m]; + fp_t[i] += rho[j]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]); + if (NEWTON_PAIR || j < nlocal) { + fp_t[j] += rho[i]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p + + coeff[6]); + } + } + } + } + + // wait until all threads are done with computation + sync_threads(); + + // communicate and sum modified densities + if (NEWTON_PAIR) { + // reduce per thread density + data_reduce_thr(&(fp[0]), nall, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { + rhofp = 2; + comm->reverse_comm_pair(this); + } + + } else { + data_reduce_thr(&(fp[0]), nlocal, comm->nthreads, 1, tid); + + // wait until reduction is complete + sync_threads(); + } + +#if defined(_OPENMP) +#pragma omp master +#endif + { + rhofp = 2; + comm->forward_comm_pair(this); + } + + // wait until master is finished communicating + sync_threads(); + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + itype = type[i]; + if (EFLAG) { + phi = 0.5*rho[i]*fp[i]; + if (eflag_global) eng_vdwl_thr[tid] += phi; + if (eflag_atom) eatom_thr[tid][i] += phi; + } + } + + // compute forces on each atom + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + fxtmp = fytmp = fztmp = 0.0; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + 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 < cutforcesq[itype][jtype]) { + r = sqrt(rsq); + p = r*rdr + 1.0; + m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + + coeff = Fij_spline[type2Fij[jtype][itype]][m]; + rhoip = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = Fij_spline[type2Fij[itype][jtype]][m]; + rhojp = (coeff[0]*p + coeff[1])*p + coeff[2]; + coeff = phiij_spline[type2phiij[itype][jtype]][m]; + phip = (coeff[0]*p + coeff[1])*p + coeff[2]; + phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coeff = Gij_spline[type2Gij[itype][jtype]][m]; + coul = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + coulp = (coeff[0]*p + coeff[1])*p + coeff[2]; + psip = phip + (rho[i]*rho[j]-q0[itype]*q0[jtype])*coulp + + fp[i]*rhojp + fp[j]*rhoip; + recip = 1.0/r; + fpair = -psip*recip; + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) evdwl = phi-q0[itype]*q0[jtype]*coul; + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairEIMOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairEIM::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_eim_omp.h b/src/USER-OMP/pair_eim_omp.h new file mode 100644 index 0000000000..3693492e09 --- /dev/null +++ b/src/USER-OMP/pair_eim_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eim/omp,PairEIMOMP) + +#else + +#ifndef LMP_PAIR_EIM_OMP_H +#define LMP_PAIR_EIM_OMP_H + +#include "pair_eim.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairEIMOMP : public PairEIM, public ThrOMP { + + public: + PairEIMOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double *rho_t, double *fp_t, int iifrom, int iito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_gauss_omp.cpp b/src/USER-OMP/pair_gauss_omp.cpp new file mode 100644 index 0000000000..e8b255d0b7 --- /dev/null +++ b/src/USER-OMP/pair_gauss_omp.cpp @@ -0,0 +1,170 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_gauss_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EPSILON 1.0e-10 +/* ---------------------------------------------------------------------- */ + +PairGaussOMP::PairGaussOMP(LAMMPS *lmp) : + PairGauss(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairGaussOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairGaussOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double r,rsq,r2inv,forcelj,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + int occ = 0; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]; + + // define a Gaussian well to be occupied if + // the site it interacts with is within the force maximum + + if (EFLAG) + if (eflag_global && rsq < 0.5/b[itype][jtype]) occ++; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + r = sqrt(rsq); + forcelj = - 2.0*a[itype][jtype]*b[itype][jtype] * rsq * + exp(-b[itype][jtype]*rsq); + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = -(a[itype][jtype]*exp(-b[itype][jtype]*rsq) - + offset[itype][jtype]); + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } + if (eflag_global) pvector[0] = occ; +} + +/* ---------------------------------------------------------------------- */ + +double PairGaussOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairGauss::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_gauss_omp.h b/src/USER-OMP/pair_gauss_omp.h new file mode 100644 index 0000000000..7f8fc9a85b --- /dev/null +++ b/src/USER-OMP/pair_gauss_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(gauss/omp,PairGaussOMP) + +#else + +#ifndef LMP_PAIR_GAUSS_OMP_H +#define LMP_PAIR_GAUSS_OMP_H + +#include "pair_gauss.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairGaussOMP : public PairGauss, public ThrOMP { + + public: + PairGaussOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_gayberne_omp.cpp b/src/USER-OMP/pair_gayberne_omp.cpp new file mode 100644 index 0000000000..ff115e8ef7 --- /dev/null +++ b/src/USER-OMP/pair_gayberne_omp.cpp @@ -0,0 +1,227 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_gayberne_omp.h" +#include "math_extra.h" +#include "atom.h" +#include "comm.h" +#include "atom_vec_ellipsoid.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairGayBerneOMP::PairGayBerneOMP(LAMMPS *lmp) : + PairGayBerne(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairGayBerneOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid); + else eval<1,1,0>(f, torque, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid); + else eval<1,0,0>(f, torque, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid); + else eval<0,0,0>(f, torque, ifrom, ito, tid); + } + + // reduce per thread forces and torques into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairGayBerneOMP::eval(double **f, double **tor, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj; + double fforce[3],ttor[3],rtor[3],r12[3]; + double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3]; + int *ilist,*jlist,*numneigh,**firstneigh; + double *iquat,*jquat; + + double **x = atom->x; + int *ellipsoid = atom->ellipsoid; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + + AtomVecEllipsoid::Bonus *bonus = avec->bonus; + + double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itype = type[i]; + + if (form[itype][itype] == ELLIPSE_ELLIPSE) { + iquat = bonus[ellipsoid[i]].quat; + MathExtra::quat_to_mat_trans(iquat,a1); + MathExtra::diag_times3(well[itype],a1,temp); + MathExtra::transpose_times3(a1,temp,b1); + MathExtra::diag_times3(shape2[itype],a1,temp); + MathExtra::transpose_times3(a1,temp,g1); + } + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + // r12 = center to center vector + + r12[0] = x[j][0]-x[i][0]; + r12[1] = x[j][1]-x[i][1]; + r12[2] = x[j][2]-x[i][2]; + rsq = MathExtra::dot3(r12,r12); + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + + switch (form[itype][jtype]) { + case SPHERE_SPHERE: + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= -r2inv; + if (EFLAG) + one_eng = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) - + offset[itype][jtype]; + fforce[0] = r12[0]*forcelj; + fforce[1] = r12[1]*forcelj; + fforce[2] = r12[2]*forcelj; + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2] = 0.0; + break; + + case SPHERE_ELLIPSE: + jquat = bonus[ellipsoid[j]].quat; + MathExtra::quat_to_mat_trans(jquat,a2); + MathExtra::diag_times3(well[jtype],a2,temp); + MathExtra::transpose_times3(a2,temp,b2); + MathExtra::diag_times3(shape2[jtype],a2,temp); + MathExtra::transpose_times3(a2,temp,g2); + one_eng = gayberne_lj(j,i,a2,b2,g2,r12,rsq,fforce,rtor); + ttor[0] = ttor[1] = ttor[2] = 0.0; + break; + + case ELLIPSE_SPHERE: + one_eng = gayberne_lj(i,j,a1,b1,g1,r12,rsq,fforce,ttor); + rtor[0] = rtor[1] = rtor[2] = 0.0; + break; + + default: + jquat = bonus[ellipsoid[j]].quat; + MathExtra::quat_to_mat_trans(jquat,a2); + MathExtra::diag_times3(well[jtype],a2,temp); + MathExtra::transpose_times3(a2,temp,b2); + MathExtra::diag_times3(shape2[jtype],a2,temp); + MathExtra::transpose_times3(a2,temp,g2); + one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq, + fforce,ttor,rtor); + break; + } + + fforce[0] *= factor_lj; + fforce[1] *= factor_lj; + fforce[2] *= factor_lj; + ttor[0] *= factor_lj; + ttor[1] *= factor_lj; + ttor[2] *= factor_lj; + + f[i][0] += fforce[0]; + f[i][1] += fforce[1]; + f[i][2] += fforce[2]; + tor[i][0] += ttor[0]; + tor[i][1] += ttor[1]; + tor[i][2] += ttor[2]; + + if (NEWTON_PAIR || j < nlocal) { + rtor[0] *= factor_lj; + rtor[1] *= factor_lj; + rtor[2] *= factor_lj; + f[j][0] -= fforce[0]; + f[j][1] -= fforce[1]; + f[j][2] -= fforce[2]; + tor[j][0] += rtor[0]; + tor[j][1] += rtor[1]; + tor[j][2] += rtor[2]; + } + + if (EFLAG) evdwl = factor_lj*one_eng; + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fforce[0],fforce[1],fforce[2], + -r12[0],-r12[1],-r12[2],tid); + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGayBerneOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairGayBerne::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_gayberne_omp.h b/src/USER-OMP/pair_gayberne_omp.h new file mode 100644 index 0000000000..737b4ec67d --- /dev/null +++ b/src/USER-OMP/pair_gayberne_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(gayberne/omp,PairGayBerneOMP) + +#else + +#ifndef LMP_PAIR_GAYBERNE_OMP_H +#define LMP_PAIR_GAYBERNE_OMP_H + +#include "pair_gayberne.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairGayBerneOMP : public PairGayBerne, public ThrOMP { + + public: + PairGayBerneOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.cpp b/src/USER-OMP/pair_gran_hertz_history_omp.cpp new file mode 100644 index 0000000000..1866833afe --- /dev/null +++ b/src/USER-OMP/pair_gran_hertz_history_omp.cpp @@ -0,0 +1,298 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_gran_hertz_history_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "update.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairGranHertzHistoryOMP::PairGranHertzHistoryOMP(LAMMPS *lmp) : + PairGranHertzHistory(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHertzHistoryOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int shearupdate = (update->ntimestep > laststep) ? 1 : 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) + if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid); + else eval<1,0>(f, torque, ifrom, ito, tid); + else + if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid); + else eval<0,0>(f, torque, ifrom, ito, tid); + + // reduce per thread forces and torque into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + + laststep = update->ntimestep; +} + +template +void PairGranHertzHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double meff,damp,ccel,tor1,tor2,tor3; + double fn,fs,fs1,fs2,fs3; + double shrmag,rsht,polyhertz; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + double **x = atom->x; + double **v = atom->v; + double **omega = atom->omega; + double *radius = atom->radius; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double fxtmp,fytmp,fztmp; + double t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = list->listgranhistory->firstneigh; + firstshear = list->listgranhistory->firstdouble; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + touch = firsttouch[i]; + allshear = firstshear[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + + if (rsq >= radsum*radsum) { + + // unset non-touching neighbors + + touch[jj] = 0; + shear = &allshear[3*jj]; + shear[0] = 0.0; + shear[1] = 0.0; + shear[2] = 0.0; + + } else { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + // relative translational velocity + + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + vnnr = vr1*delx + vr2*dely + vr3*delz; + vn1 = delx*vnnr * rsqinv; + vn2 = dely*vnnr * rsqinv; + vn3 = delz*vnnr * rsqinv; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv; + wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv; + wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv; + + // normal force = Hertzian contact + normal velocity damping + + if (rmass) { + meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]); + if (mask[i] & freeze_group_bit) meff = rmass[j]; + if (mask[j] & freeze_group_bit) meff = rmass[i]; + } else { + itype = type[i]; + jtype = type[j]; + meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]); + if (mask[i] & freeze_group_bit) meff = mass[jtype]; + if (mask[j] & freeze_group_bit) meff = mass[itype]; + } + + damp = meff*gamman*vnnr*rsqinv; + ccel = kn*(radsum-r)*rinv - damp; + polyhertz = sqrt((radsum-r)*radi*radj / radsum); + ccel *= polyhertz; + + // relative velocities + + vtr1 = vt1 - (delz*wr2-dely*wr3); + vtr2 = vt2 - (delx*wr3-delz*wr1); + vtr3 = vt3 - (dely*wr1-delx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + + touch[jj] = 1; + shear = &allshear[3*jj]; + + if (SHEARUPDATE) { + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // rotate shear displacements + + rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz; + rsht *= rsqinv; + if (SHEARUPDATE) { + shear[0] -= rsht*delx; + shear[1] -= rsht*dely; + shear[2] -= rsht*delz; + } + + // tangential forces = shear + tangential velocity damping + + fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1); + fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2); + fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3); + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + fn = xmu * fabs(ccel*r); + + if (fs > fn) { + if (shrmag != 0.0) { + const double fnfs = fn/fs; + const double mgkt = meff*gammat/kt; + shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1; + shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2; + shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3; + fs1 *= fnfs; + fs2 *= fnfs; + fs3 *= fnfs; + } else fs1 = fs2 = fs3 = 0.0; + } + + // forces & torques + + fx = delx*ccel + fs1; + fy = dely*ccel + fs2; + fz = delz*ccel + fs3; + fxtmp += fx; + fytmp += fy; + fztmp += fz; + + tor1 = rinv * (dely*fs3 - delz*fs2); + tor2 = rinv * (delz*fs1 - delx*fs3); + tor3 = rinv * (delx*fs2 - dely*fs1); + t1tmp -= radi*tor1; + t2tmp -= radi*tor2; + t3tmp -= radi*tor3; + + if (j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + torque[j][0] -= radj*tor1; + torque[j][1] -= radj*tor2; + torque[j][2] -= radj*tor3; + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0, + 0.0,0.0,fx,fy,fz,delx,dely,delz,tid); + + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + torque[i][0] += t1tmp; + torque[i][1] += t2tmp; + torque[i][2] += t3tmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranHertzHistoryOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairGranHertzHistory::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.h b/src/USER-OMP/pair_gran_hertz_history_omp.h new file mode 100644 index 0000000000..66d7bc0fa5 --- /dev/null +++ b/src/USER-OMP/pair_gran_hertz_history_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(gran/hertz/history/omp,PairGranHertzHistoryOMP) + +#else + +#ifndef LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H +#define LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H + +#include "pair_gran_hertz_history.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairGranHertzHistoryOMP : public PairGranHertzHistory, public ThrOMP { + + public: + PairGranHertzHistoryOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.cpp b/src/USER-OMP/pair_gran_hooke_history_omp.cpp new file mode 100644 index 0000000000..ad0537b516 --- /dev/null +++ b/src/USER-OMP/pair_gran_hooke_history_omp.cpp @@ -0,0 +1,301 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_gran_hooke_history_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "update.h" + +#include "string.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairGranHookeHistoryOMP::PairGranHookeHistoryOMP(LAMMPS *lmp) : + PairGranHookeHistory(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + // trigger use of OpenMP version of FixShearHistory + suffix = new char[4]; + memcpy(suffix,"omp",4); +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHookeHistoryOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int shearupdate = (update->ntimestep > laststep) ? 1 : 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) + if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid); + else eval<1,0>(f, torque, ifrom, ito, tid); + else + if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid); + else eval<0,0>(f, torque, ifrom, ito, tid); + + // reduce per thread forces and torque into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + + laststep = update->ntimestep; +} + +template +void PairGranHookeHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double meff,damp,ccel,tor1,tor2,tor3; + double fn,fs,fs1,fs2,fs3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + double **x = atom->x; + double **v = atom->v; + double **omega = atom->omega; + double *radius = atom->radius; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double fxtmp,fytmp,fztmp; + double t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + touch = firsttouch[i]; + allshear = firstshear[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + + if (rsq >= radsum*radsum) { + + // unset non-touching neighbors + + touch[jj] = 0; + shear = &allshear[3*jj]; + shear[0] = 0.0; + shear[1] = 0.0; + shear[2] = 0.0; + + } else { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + // relative translational velocity + + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + vnnr = vr1*delx + vr2*dely + vr3*delz; + vn1 = delx*vnnr * rsqinv; + vn2 = dely*vnnr * rsqinv; + vn3 = delz*vnnr * rsqinv; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv; + wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv; + wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv; + + // normal forces = Hookian contact + normal velocity damping + + if (rmass) { + meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]); + if (mask[i] & freeze_group_bit) meff = rmass[j]; + if (mask[j] & freeze_group_bit) meff = rmass[i]; + } else { + itype = type[i]; + jtype = type[j]; + meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]); + if (mask[i] & freeze_group_bit) meff = mass[jtype]; + if (mask[j] & freeze_group_bit) meff = mass[itype]; + } + + damp = meff*gamman*vnnr*rsqinv; + ccel = kn*(radsum-r)*rinv - damp; + + // relative velocities + + vtr1 = vt1 - (delz*wr2-dely*wr3); + vtr2 = vt2 - (delx*wr3-delz*wr1); + vtr3 = vt3 - (dely*wr1-delx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + + touch[jj] = 1; + shear = &allshear[3*jj]; + + if (SHEARUPDATE) { + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // rotate shear displacements + + rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz; + rsht *= rsqinv; + if (SHEARUPDATE) { + shear[0] -= rsht*delx; + shear[1] -= rsht*dely; + shear[2] -= rsht*delz; + } + + // tangential forces = shear + tangential velocity damping + + fs1 = - (kt*shear[0] + meff*gammat*vtr1); + fs2 = - (kt*shear[1] + meff*gammat*vtr2); + fs3 = - (kt*shear[2] + meff*gammat*vtr3); + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + fn = xmu * fabs(ccel*r); + + if (fs > fn) { + if (shrmag != 0.0) { + const double fnfs = fn/fs; + const double mgkt = meff*gammat/kt; + shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1; + shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2; + shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3; + fs1 *= fnfs; + fs2 *= fnfs; + fs3 *= fnfs; + } else fs1 = fs2 = fs3 = 0.0; + } + + // forces & torques + + fx = delx*ccel + fs1; + fy = dely*ccel + fs2; + fz = delz*ccel + fs3; + fxtmp += fx; + fytmp += fy; + fztmp += fz; + + tor1 = rinv * (dely*fs3 - delz*fs2); + tor2 = rinv * (delz*fs1 - delx*fs3); + tor3 = rinv * (delx*fs2 - dely*fs1); + t1tmp -= radi*tor1; + t2tmp -= radi*tor2; + t3tmp -= radi*tor3; + + if (j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + torque[j][0] -= radj*tor1; + torque[j][1] -= radj*tor2; + torque[j][2] -= radj*tor3; + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0, + 0.0,0.0,fx,fy,fz,delx,dely,delz,tid); + + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + torque[i][0] += t1tmp; + torque[i][1] += t2tmp; + torque[i][2] += t3tmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranHookeHistoryOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairGranHookeHistory::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.h b/src/USER-OMP/pair_gran_hooke_history_omp.h new file mode 100644 index 0000000000..33325025fc --- /dev/null +++ b/src/USER-OMP/pair_gran_hooke_history_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(gran/hooke/history/omp,PairGranHookeHistoryOMP) + +#else + +#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H +#define LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H + +#include "pair_gran_hooke_history.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairGranHookeHistoryOMP : public PairGranHookeHistory, public ThrOMP { + + public: + PairGranHookeHistoryOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_gran_hooke_omp.cpp b/src/USER-OMP/pair_gran_hooke_omp.cpp new file mode 100644 index 0000000000..d6991fa453 --- /dev/null +++ b/src/USER-OMP/pair_gran_hooke_omp.cpp @@ -0,0 +1,240 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_gran_hooke_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairGranHookeOMP::PairGranHookeOMP(LAMMPS *lmp) : + PairGranHooke(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHookeOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) + if (force->newton_pair) eval<1,1>(f, torque, ifrom, ito, tid); + else eval<1,0>(f, torque, ifrom, ito, tid); + else + if (force->newton_pair) eval<0,1>(f, torque, ifrom, ito, tid); + else eval<0,0>(f, torque, ifrom, ito, tid); + + // reduce per thread forces and torque into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); +} + +template +void PairGranHookeOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double meff,damp,ccel,tor1,tor2,tor3; + double fn,fs,ft,fs1,fs2,fs3; + int *ilist,*jlist,*numneigh,**firstneigh; + + double **x = atom->x; + double **v = atom->v; + double **omega = atom->omega; + double *radius = atom->radius; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double fxtmp,fytmp,fztmp; + double t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + + if (rsq < radsum*radsum) { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + // relative translational velocity + + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + vnnr = vr1*delx + vr2*dely + vr3*delz; + vn1 = delx*vnnr * rsqinv; + vn2 = dely*vnnr * rsqinv; + vn3 = delz*vnnr * rsqinv; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv; + wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv; + wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv; + + // normal forces = Hookian contact + normal velocity damping + + if (rmass) { + meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]); + if (mask[i] & freeze_group_bit) meff = rmass[j]; + if (mask[j] & freeze_group_bit) meff = rmass[i]; + } else { + itype = type[i]; + jtype = type[j]; + meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]); + if (mask[i] & freeze_group_bit) meff = mass[jtype]; + if (mask[j] & freeze_group_bit) meff = mass[itype]; + } + + damp = meff*gamman*vnnr*rsqinv; + ccel = kn*(radsum-r)*rinv - damp; + + // relative velocities + + vtr1 = vt1 - (delz*wr2-dely*wr3); + vtr2 = vt2 - (delx*wr3-delz*wr1); + vtr3 = vt3 - (dely*wr1-delx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // force normalization + + fn = xmu * fabs(ccel*r); + fs = meff*gammat*vrel; + if (vrel != 0.0) ft = MIN(fn,fs) / vrel; + else ft = 0.0; + + // tangential force due to tangential velocity damping + + fs1 = -ft*vtr1; + fs2 = -ft*vtr2; + fs3 = -ft*vtr3; + + // forces & torques + + fx = delx*ccel + fs1; + fy = dely*ccel + fs2; + fz = delz*ccel + fs3; + fxtmp += fx; + fytmp += fy; + fztmp += fz; + + tor1 = rinv * (dely*fs3 - delz*fs2); + tor2 = rinv * (delz*fs1 - delx*fs3); + tor3 = rinv * (delx*fs2 - dely*fs1); + t1tmp -= radi*tor1; + t2tmp -= radi*tor2; + t3tmp -= radi*tor3; + + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + torque[j][0] -= radj*tor1; + torque[j][1] -= radj*tor2; + torque[j][2] -= radj*tor3; + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + 0.0,0.0,fx,fy,fz,delx,dely,delz,tid); + + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + torque[i][0] += t1tmp; + torque[i][1] += t2tmp; + torque[i][2] += t3tmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranHookeOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairGranHooke::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_gran_hooke_omp.h b/src/USER-OMP/pair_gran_hooke_omp.h new file mode 100644 index 0000000000..f2b093778c --- /dev/null +++ b/src/USER-OMP/pair_gran_hooke_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(gran/hooke/omp,PairGranHookeOMP) + +#else + +#ifndef LMP_PAIR_GRAN_HOOKE_OMP_H +#define LMP_PAIR_GRAN_HOOKE_OMP_H + +#include "pair_gran_hooke.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairGranHookeOMP : public PairGranHooke, public ThrOMP { + + public: + PairGranHookeOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp new file mode 100644 index 0000000000..012fd596b3 --- /dev/null +++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp @@ -0,0 +1,299 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_hbond_dreiding_lj_omp.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +PairHbondDreidingLJOMP::PairHbondDreidingLJOMP(LAMMPS *lmp) : + PairHbondDreidingLJ(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + hbcount_thr = hbeng_thr = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairHbondDreidingLJOMP::~PairHbondDreidingLJOMP() +{ + respa_enable = 0; + if (hbcount_thr) { + delete[] hbcount_thr; + delete[] hbeng_thr; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairHbondDreidingLJOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + if (!hbcount_thr) { + hbcount_thr = new double[nthreads]; + hbeng_thr = new double[nthreads]; + } + + for (int i=0; i < nthreads; ++i) { + hbcount_thr[i] = 0.0; + hbeng_thr[i] = 0.0; + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); + + // reduce per thread hbond data + if (eflag_global) { + pvector[0] = 0.0; + pvector[1] = 0.0; + for (int i=0; i < nthreads; ++i) { + pvector[0] += hbcount_thr[i]; + pvector[1] += hbeng_thr[i]; + } + } +} + +template +void PairHbondDreidingLJOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2; + double factor_hb,force_angle,force_kernel,evdwl,eng_lj; + double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; + double fi[3],fj[3],delr1[3],delr2[3]; + double r2inv,r10inv; + double switch1,switch2; + int *ilist,*jlist,*klist,*numneigh,**firstneigh; + Param *pm; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int **special = atom->special; + int **nspecial = atom->nspecial; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + + // ii = loop over donors + // jj = loop over acceptors + // kk = loop over hydrogens bonded to donor + + int hbcount = 0; + double hbeng = 0.0; + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itype = type[i]; + if (!donor[itype]) continue; + + klist = special[i]; + knum = nspecial[i][0]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_hb = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + jtype = type[j]; + if (!acceptor[jtype]) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + for (kk = 0; kk < knum; kk++) { + k = atom->map(klist[kk]); + if (k < 0) continue; + ktype = type[k]; + m = type2param[itype][jtype][ktype]; + if (m < 0) continue; + pm = ¶ms[m]; + + if (rsq < pm->cut_outersq) { + delr1[0] = xtmp - x[k][0]; + delr1[1] = ytmp - x[k][1]; + delr1[2] = ztmp - x[k][2]; + domain->minimum_image(delr1); + rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; + r1 = sqrt(rsq1); + + delr2[0] = x[j][0] - x[k][0]; + delr2[1] = x[j][1] - x[k][1]; + delr2[2] = x[j][2] - x[k][2]; + domain->minimum_image(delr2); + rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; + r2 = sqrt(rsq2); + + // angle (cos and sin) + + c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2]; + c /= r1*r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + ac = acos(c); + + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { + s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + + // LJ-specific kernel + + r2inv = 1.0/rsq; + r10inv = r2inv*r2inv*r2inv*r2inv*r2inv; + force_kernel = r10inv*(pm->lj1*r2inv - pm->lj2)*r2inv * + pow(c,pm->ap); + force_angle = pm->ap * r10inv*(pm->lj3*r2inv - pm->lj4) * + pow(c,pm->ap-1)*s; + + eng_lj = r10inv*(pm->lj3*r2inv - pm->lj4); + if (rsq > pm->cut_innersq) { + switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) * + (pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) / + pm->denom_vdw; + switch2 = 12.0*rsq * (pm->cut_outersq-rsq) * + (rsq-pm->cut_innersq) / pm->denom_vdw; + force_kernel = force_kernel*switch1 + eng_lj*switch2; + eng_lj *= switch1; + } + + if (EFLAG) { + evdwl = eng_lj * pow(c,pm->ap); + evdwl *= factor_hb; + } + + a = factor_hb*force_angle/s; + b = factor_hb*force_kernel; + + a11 = a*c / rsq1; + a12 = -a / (r1*r2); + a22 = a*c / rsq2; + + vx1 = a11*delr1[0] + a12*delr2[0]; + vx2 = a22*delr2[0] + a12*delr1[0]; + vy1 = a11*delr1[1] + a12*delr2[1]; + vy2 = a22*delr2[1] + a12*delr1[1]; + vz1 = a11*delr1[2] + a12*delr2[2]; + vz2 = a22*delr2[2] + a12*delr1[2]; + + fi[0] = vx1 + b*delx; + fi[1] = vy1 + b*dely; + fi[2] = vz1 + b*delz; + fj[0] = vx2 - b*delx; + fj[1] = vy2 - b*dely; + fj[2] = vz2 - b*delz; + + fxtmp += fi[0]; + fytmp += fi[1]; + fztmp += fi[2]; + + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + + f[k][0] -= vx1 + vx2; + f[k][1] -= vy1 + vy2; + f[k][2] -= vz1 + vz2; + + // KIJ instead of IJK b/c delr1/delr2 are both with respect to k + + if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid); + if (EFLAG) { + hbcount++; + hbeng += evdwl; + } + } + } + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } + hbcount_thr[tid] = static_cast(hbcount); + hbeng_thr[tid] = hbeng; +} + +/* ---------------------------------------------------------------------- */ + +double PairHbondDreidingLJOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += comm->nthreads * 2 * sizeof(double); + bytes += PairHbondDreidingLJ::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.h b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h new file mode 100644 index 0000000000..1aef78490c --- /dev/null +++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(hbond/dreiding/lj/omp,PairHbondDreidingLJOMP) + +#else + +#ifndef LMP_PAIR_HBOND_DREIDING_LJ_OMP_H +#define LMP_PAIR_HBOND_DREIDING_LJ_OMP_H + +#include "pair_hbond_dreiding_lj.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairHbondDreidingLJOMP : public PairHbondDreidingLJ, public ThrOMP { + + public: + PairHbondDreidingLJOMP(class LAMMPS *); + virtual ~PairHbondDreidingLJOMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + double *hbcount_thr, *hbeng_thr; + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp new file mode 100644 index 0000000000..b6c966f8c7 --- /dev/null +++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_hbond_dreiding_morse_omp.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +PairHbondDreidingMorseOMP::PairHbondDreidingMorseOMP(LAMMPS *lmp) : + PairHbondDreidingMorse(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + hbcount_thr = hbeng_thr = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairHbondDreidingMorseOMP::~PairHbondDreidingMorseOMP() +{ + respa_enable = 0; + if (hbcount_thr) { + delete[] hbcount_thr; + delete[] hbeng_thr; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairHbondDreidingMorseOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + if (!hbcount_thr) { + hbcount_thr = new double[nthreads]; + hbeng_thr = new double[nthreads]; + } + + for (int i=0; i < nthreads; ++i) { + hbcount_thr[i] = 0.0; + hbeng_thr[i] = 0.0; + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); + + // reduce per thread hbond data + if (eflag_global) { + pvector[0] = 0.0; + pvector[1] = 0.0; + for (int i=0; i < nthreads; ++i) { + pvector[0] += hbcount_thr[i]; + pvector[1] += hbeng_thr[i]; + } + } +} + +template +void PairHbondDreidingMorseOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2; + double factor_hb,force_angle,force_kernel,evdwl; + double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; + double fi[3],fj[3],delr1[3],delr2[3]; + double r,dr,dexp,eng_morse,switch1,switch2; + int *ilist,*jlist,*klist,*numneigh,**firstneigh; + Param *pm; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int **special = atom->special; + int **nspecial = atom->nspecial; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + + // ii = loop over donors + // jj = loop over acceptors + // kk = loop over hydrogens bonded to donor + + int hbcount = 0; + double hbeng = 0.0; + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itype = type[i]; + if (!donor[itype]) continue; + + klist = special[i]; + knum = nspecial[i][0]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_hb = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + jtype = type[j]; + if (!acceptor[jtype]) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + for (kk = 0; kk < knum; kk++) { + k = atom->map(klist[kk]); + if (k < 0) continue; + ktype = type[k]; + m = type2param[itype][jtype][ktype]; + if (m < 0) continue; + pm = ¶ms[m]; + + if (rsq < pm->cut_outersq) { + delr1[0] = xtmp - x[k][0]; + delr1[1] = ytmp - x[k][1]; + delr1[2] = ztmp - x[k][2]; + domain->minimum_image(delr1); + rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; + r1 = sqrt(rsq1); + + delr2[0] = x[j][0] - x[k][0]; + delr2[1] = x[j][1] - x[k][1]; + delr2[2] = x[j][2] - x[k][2]; + domain->minimum_image(delr2); + rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; + r2 = sqrt(rsq2); + + // angle (cos and sin) + + c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2]; + c /= r1*r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + ac = acos(c); + + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { + s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + + // Morse-specific kernel + + r = sqrt(rsq); + dr = r - pm->r0; + dexp = exp(-pm->alpha * dr); + force_kernel = pm->morse1*(dexp*dexp - dexp)/r * pow(c,pm->ap); + force_angle = pm->ap * eng_morse * pow(c,pm->ap-1)*s; + + eng_morse = pm->d0 * (dexp*dexp - 2.0*dexp); + if (rsq > pm->cut_innersq) { + switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) * + (pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) / + pm->denom_vdw; + switch2 = 12.0*rsq * (pm->cut_outersq-rsq) * + (rsq-pm->cut_innersq) / pm->denom_vdw; + force_kernel = force_kernel*switch1 + eng_morse*switch2; + eng_morse *= switch1; + } + + if (EFLAG) { + evdwl = eng_morse * pow(c,params[m].ap); + evdwl *= factor_hb; + } + + a = factor_hb*force_angle/s; + b = factor_hb*force_kernel; + + a11 = a*c / rsq1; + a12 = -a / (r1*r2); + a22 = a*c / rsq2; + + vx1 = a11*delr1[0] + a12*delr2[0]; + vx2 = a22*delr2[0] + a12*delr1[0]; + vy1 = a11*delr1[1] + a12*delr2[1]; + vy2 = a22*delr2[1] + a12*delr1[1]; + vz1 = a11*delr1[2] + a12*delr2[2]; + vz2 = a22*delr2[2] + a12*delr1[2]; + + fi[0] = vx1 + b*delx; + fi[1] = vy1 + b*dely; + fi[2] = vz1 + b*delz; + fj[0] = vx2 - b*delx; + fj[1] = vy2 - b*dely; + fj[2] = vz2 - b*delz; + + fxtmp += fi[0]; + fytmp += fi[1]; + fztmp += fi[2]; + + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + + f[k][0] -= vx1 + vx2; + f[k][1] -= vy1 + vy2; + f[k][2] -= vz1 + vz2; + + // KIJ instead of IJK b/c delr1/delr2 are both with respect to k + + if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid); + if (EFLAG) { + hbcount++; + hbeng += evdwl; + } + } + } + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } + hbcount_thr[tid] = static_cast(hbcount); + hbeng_thr[tid] = hbeng; +} + +/* ---------------------------------------------------------------------- */ + +double PairHbondDreidingMorseOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += comm->nthreads * 2 * sizeof(double); + bytes += PairHbondDreidingMorse::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.h b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h new file mode 100644 index 0000000000..2a13c618c6 --- /dev/null +++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(hbond/dreiding/morse/omp,PairHbondDreidingMorseOMP) + +#else + +#ifndef LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H +#define LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H + +#include "pair_hbond_dreiding_morse.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairHbondDreidingMorseOMP : public PairHbondDreidingMorse, public ThrOMP { + + public: + PairHbondDreidingMorseOMP(class LAMMPS *); + virtual ~PairHbondDreidingMorseOMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + double *hbcount_thr, *hbeng_thr; + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj96_cut_omp.cpp b/src/USER-OMP/pair_lj96_cut_omp.cpp new file mode 100644 index 0000000000..f0998363e1 --- /dev/null +++ b/src/USER-OMP/pair_lj96_cut_omp.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj96_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJ96CutOMP::PairLJ96CutOMP(LAMMPS *lmp) : + PairLJ96Cut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJ96CutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJ96CutOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + r3inv = sqrt(r6inv); + + forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) + - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJ96CutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJ96Cut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj96_cut_omp.h b/src/USER-OMP/pair_lj96_cut_omp.h new file mode 100644 index 0000000000..333212303d --- /dev/null +++ b/src/USER-OMP/pair_lj96_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj96/cut/omp,PairLJ96CutOMP) + +#else + +#ifndef LMP_PAIR_LJ96_CUT_OMP_H +#define LMP_PAIR_LJ96_CUT_OMP_H + +#include "pair_lj96_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJ96CutOMP : public PairLJ96Cut, public ThrOMP { + + public: + PairLJ96CutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp new file mode 100644 index 0000000000..32ad05acda --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp @@ -0,0 +1,213 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_charmm_coul_charmm_implicit_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJCharmmCoulCharmmImplicitOMP::PairLJCharmmCoulCharmmImplicitOMP(LAMMPS *lmp) : + PairLJCharmmCoulCharmmImplicit(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCharmmCoulCharmmImplicitOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCharmmCoulCharmmImplicitOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double philj,switch1,switch2; + double invdenom_coul,invdenom_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0; + invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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 < cut_bothsq) { + r2inv = 1.0/rsq; + + if (rsq < cut_coulsq) { + forcecoul = 2.0 * qqrd2e * qtmp*q[j]*r2inv; + if (rsq > cut_coul_innersq) { + switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * + (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * invdenom_coul; + switch2 = 12.0*rsq * (cut_coulsq-rsq) * + (rsq-cut_coul_innersq) * invdenom_coul; + forcecoul *= switch1 + switch2; + } + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j]; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj; + switch2 = 12.0*rsq * (cut_ljsq-rsq) * + (rsq-cut_lj_innersq) * invdenom_lj; + philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + forcelj = forcelj*switch1 + philj*switch2; + } + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = qqrd2e * qtmp*q[j]*r2inv; + if (rsq > cut_coul_innersq) { + switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * + (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * + invdenom_coul; + ecoul *= switch1; + } + ecoul *= factor_coul; + } else ecoul = 0.0; + if (rsq < cut_ljsq) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj; + evdwl *= switch1; + } + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCharmmCoulCharmmImplicitOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCharmmCoulCharmmImplicit::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h new file mode 100644 index 0000000000..ba016d7d3d --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/charmm/coul/charmm/implicit/omp,PairLJCharmmCoulCharmmImplicitOMP) + +#else + +#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H +#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H + +#include "pair_lj_charmm_coul_charmm_implicit.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCharmmCoulCharmmImplicitOMP : public PairLJCharmmCoulCharmmImplicit, public ThrOMP { + + public: + PairLJCharmmCoulCharmmImplicitOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp new file mode 100644 index 0000000000..6dac7a17f6 --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp @@ -0,0 +1,213 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_charmm_coul_charmm_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJCharmmCoulCharmmOMP::PairLJCharmmCoulCharmmOMP(LAMMPS *lmp) : + PairLJCharmmCoulCharmm(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCharmmCoulCharmmOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCharmmCoulCharmmOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double philj,switch1,switch2; + double invdenom_coul,invdenom_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0; + invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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 < cut_bothsq) { + r2inv = 1.0/rsq; + + if (rsq < cut_coulsq) { + forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); + if (rsq > cut_coul_innersq) { + switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * + (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * invdenom_coul; + switch2 = 12.0*rsq * (cut_coulsq-rsq) * + (rsq-cut_coul_innersq) * invdenom_coul; + forcecoul *= switch1 + switch2; + } + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j]; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj; + switch2 = 12.0*rsq * (cut_ljsq-rsq) * + (rsq-cut_lj_innersq) * invdenom_lj; + philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + forcelj = forcelj*switch1 + philj*switch2; + } + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); + if (rsq > cut_coul_innersq) { + switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * + (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * + invdenom_coul; + ecoul *= switch1; + } + ecoul *= factor_coul; + } else ecoul = 0.0; + if (rsq < cut_ljsq) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj; + evdwl *= switch1; + } + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCharmmCoulCharmmOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCharmmCoulCharmm::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h new file mode 100644 index 0000000000..f2889b05fe --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/charmm/coul/charmm/omp,PairLJCharmmCoulCharmmOMP) + +#else + +#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H +#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H + +#include "pair_lj_charmm_coul_charmm.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCharmmCoulCharmmOMP : public PairLJCharmmCoulCharmm, public ThrOMP { + + public: + PairLJCharmmCoulCharmmOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp new file mode 100644 index 0000000000..c99f27f2e1 --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp @@ -0,0 +1,234 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_charmm_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairLJCharmmCoulLongOMP::PairLJCharmmCoulLongOMP(LAMMPS *lmp) : + PairLJCharmmCoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCharmmCoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCharmmCoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype,itable; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double fraction,table; + double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + double philj,switch1,switch2; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + } else forcecoul = 0.0; + + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j]; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; + switch2 = 12.0*rsq * (cut_ljsq-rsq) * + (rsq-cut_lj_innersq) / denom_lj; + philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + forcelj = forcelj*switch1 + philj*switch2; + } + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = qtmp*q[j] * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + + if (rsq < cut_ljsq) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + if (rsq > cut_lj_innersq) { + switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * + (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; + evdwl *= switch1; + } + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCharmmCoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCharmmCoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h new file mode 100644 index 0000000000..b14e4c1fe4 --- /dev/null +++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/charmm/coul/long/omp,PairLJCharmmCoulLongOMP) + +#else + +#ifndef LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H +#define LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H + +#include "pair_lj_charmm_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCharmmCoulLongOMP : public PairLJCharmmCoulLong, public ThrOMP { + + public: + PairLJCharmmCoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp new file mode 100644 index 0000000000..0321882793 --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp @@ -0,0 +1,185 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_class2_coul_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJClass2CoulCutOMP::PairLJClass2CoulCutOMP(LAMMPS *lmp) : + PairLJClass2CoulCut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJClass2CoulCutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJClass2CoulCutOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj; + double factor_coul,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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); + + if (rsq < cut_coulsq[itype][jtype]) { + forcecoul = qqrd2e * qtmp*q[j]*rinv; + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r3inv = r2inv*rinv; + r6inv = r3inv*r3inv; + forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) + ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv; + else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJClass2CoulCutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJClass2CoulCut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h new file mode 100644 index 0000000000..5fe4895691 --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/class2/coul/cut/omp,PairLJClass2CoulCutOMP) + +#else + +#ifndef LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H +#define LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H + +#include "pair_lj_class2_coul_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJClass2CoulCutOMP : public PairLJClass2CoulCut, public ThrOMP { + + public: + PairLJClass2CoulCutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp new file mode 100644 index 0000000000..84d26ceb14 --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp @@ -0,0 +1,201 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_class2_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairLJClass2CoulLongOMP::PairLJClass2CoulLongOMP(LAMMPS *lmp) : + PairLJClass2CoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJClass2CoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJClass2CoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double r,rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + if (rsq < cut_coulsq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + rinv = sqrt(r2inv); + r3inv = r2inv*rinv; + r6inv = r3inv*r3inv; + forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = prefactor*erfc; + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJClass2CoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJClass2CoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.h b/src/USER-OMP/pair_lj_class2_coul_long_omp.h new file mode 100644 index 0000000000..da4ac3680f --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/class2/coul/long/omp,PairLJClass2CoulLongOMP) + +#else + +#ifndef LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H +#define LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H + +#include "pair_lj_class2_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJClass2CoulLongOMP : public PairLJClass2CoulLong, public ThrOMP { + + public: + PairLJClass2CoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_class2_omp.cpp b/src/USER-OMP/pair_lj_class2_omp.cpp new file mode 100644 index 0000000000..4f5d2550fc --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_omp.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_class2_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJClass2OMP::PairLJClass2OMP(LAMMPS *lmp) : + PairLJClass2(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJClass2OMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJClass2OMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + r3inv = sqrt(r6inv); + + forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) + - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJClass2OMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJClass2::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_class2_omp.h b/src/USER-OMP/pair_lj_class2_omp.h new file mode 100644 index 0000000000..cfe24bb714 --- /dev/null +++ b/src/USER-OMP/pair_lj_class2_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/class2/omp,PairLJClass2OMP) + +#else + +#ifndef LMP_PAIR_LJ_CLASS2_OMP_H +#define LMP_PAIR_LJ_CLASS2_OMP_H + +#include "pair_lj_class2.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJClass2OMP : public PairLJClass2, public ThrOMP { + + public: + PairLJClass2OMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_coul_omp.cpp b/src/USER-OMP/pair_lj_coul_omp.cpp new file mode 100644 index 0000000000..23e2a8d906 --- /dev/null +++ b/src/USER-OMP/pair_lj_coul_omp.cpp @@ -0,0 +1,234 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_coul_omp.h" +#include "atom.h" +#include "comm.h" +#include "math_vector.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairLJCoulOMP::PairLJCoulOMP(LAMMPS *lmp) : + PairLJCoul(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCoulOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCoulOMP::eval(double **f, int iifrom, int iito, int tid) +{ + double evdwl,ecoul,fpair; + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + + double *x0 = x[0]; + double *f0 = f[0], *fi = f0; + + int *ilist = list->ilist; + + // loop over neighbors of my atoms + + int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); + int *jneigh, *jneighn, typei, typej, ni; + double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti; + double rsq, r2inv, force_coul, force_lj; + double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; + vector xi, d; + + for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms + i = ilist[ii]; fi = f0+3*i; + if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants + offseti = offset[typei = type[i]]; + lj1i = lj1[typei]; lj2i = lj2[typei]; lj3i = lj3[typei]; lj4i = lj4[typei]; + cutsqi = cutsq[typei]; cut_ljsqi = cut_ljsq[typei]; + memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); + jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i]; + + for (; jneigh= cutsqi[typej = type[j]]) continue; + r2inv = 1.0/rsq; + + if (order1 && (rsq < cut_coulsq)) { // coulombic + if (!ncoultablebits || rsq <= tabinnersq) { // series real space + register double r = sqrt(rsq), x = g_ewald*r; + register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x); + if (ni == 0) { + s *= g_ewald*exp(-x*x); + force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; + if (EFLAG) ecoul = t; + } + else { // special case + r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x); + force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r; + if (EFLAG) ecoul = t-r; + } + } // table real space + else { + register union_int_float_t t; + t.f = rsq; + register const int k = (t.i & ncoulmask)>>ncoulshiftbits; + register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; + if (ni == 0) { + force_coul = qiqj*(ftable[k]+f*dftable[k]); + if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]); + } + else { // special case + t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); + force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f); + if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f); + } + } + } + else force_coul = ecoul = 0.0; + + if (rsq < cut_ljsqi[typej]) { // lj + if (order6) { // long-range lj + register double rn = r2inv*r2inv*r2inv; + register double x2 = g2*rsq, a2 = 1.0/x2; + x2 = a2*exp(-x2)*lj4i[typej]; + if (ni == 0) { + force_lj = + (rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; + if (EFLAG) + evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2; + } + else { // special case + register double f = special_lj[ni], t = rn*(1.0-f); + force_lj = f*(rn *= rn)*lj1i[typej]- + g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej]; + if (EFLAG) + evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]; + } + } + else { // cut lj + register double rn = r2inv*r2inv*r2inv; + if (ni == 0) { + force_lj = rn*(rn*lj1i[typej]-lj2i[typej]); + if (EFLAG) evdwl = rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]; + } + else { // special case + register double f = special_lj[ni]; + force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]); + if (EFLAG) + evdwl = f * (rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]); + } + } + } + else force_lj = evdwl = 0.0; + + fpair = (force_coul+force_lj)*r2inv; + + if (NEWTON_PAIR || j < nlocal) { + register double *fj = f0+(j+(j<<1)), f; + fi[0] += f = d[0]*fpair; fj[0] -= f; + fi[1] += f = d[1]*fpair; fj[1] -= f; + fi[2] += f = d[2]*fpair; fj[2] -= f; + } + else { + fi[0] += d[0]*fpair; + fi[1] += d[1]*fpair; + fi[2] += d[2]*fpair; + } + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,d[0],d[1],d[2],tid); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCoulOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCoul::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_coul_omp.h b/src/USER-OMP/pair_lj_coul_omp.h new file mode 100644 index 0000000000..619e609ba8 --- /dev/null +++ b/src/USER-OMP/pair_lj_coul_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/coul/omp,PairLJCoulOMP) + +#else + +#ifndef LMP_PAIR_LJ_COUL_OMP_H +#define LMP_PAIR_LJ_COUL_OMP_H + +#include "pair_lj_coul.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCoulOMP : public PairLJCoul, public ThrOMP { + + public: + PairLJCoulOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cubic_omp.cpp b/src/USER-OMP/pair_lj_cubic_omp.cpp new file mode 100644 index 0000000000..4f806bd71f --- /dev/null +++ b/src/USER-OMP/pair_lj_cubic_omp.cpp @@ -0,0 +1,173 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_cubic_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; +using namespace PairLJCubicConstants; + +/* ---------------------------------------------------------------------- */ + +PairLJCubicOMP::PairLJCubicOMP(LAMMPS *lmp) : + PairLJCubic(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCubicOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJCubicOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,forcelj,factor_lj; + double r,t,rmin; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + if (rsq <= cut_inner_sq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + } else { + r = sqrt(rsq); + rmin = sigma[itype][jtype]*RT6TWO; + t = (r - cut_inner[itype][jtype])/rmin; + forcelj = epsilon[itype][jtype]*(-DPHIDS + A3*t*t/2.0)*r/rmin; + } + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq <= cut_inner_sq[itype][jtype]) + evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + else + evdwl = epsilon[itype][jtype]* + (PHIS + DPHIDS*t - A3*t*t*t/6.0); + + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCubicOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCubic::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_cubic_omp.h b/src/USER-OMP/pair_lj_cubic_omp.h new file mode 100644 index 0000000000..559a6125ab --- /dev/null +++ b/src/USER-OMP/pair_lj_cubic_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cubic/omp,PairLJCubicOMP) + +#else + +#ifndef LMP_PAIR_LJ_CUBIC_OMP_H +#define LMP_PAIR_LJ_CUBIC_OMP_H + +#include "pair_lj_cubic.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCubicOMP : public PairLJCubic, public ThrOMP { + + public: + PairLJCubicOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp new file mode 100644 index 0000000000..be98ec38fc --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp @@ -0,0 +1,183 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_cut_coul_cut_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulCutOMP::PairLJCutCoulCutOMP(LAMMPS *lmp) : + PairLJCutCoulCut(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulCutOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCutCoulCutOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,rinv,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + if (rsq < cut_coulsq[itype][jtype]) { + rinv = sqrt(r2inv); + forcecoul = qqrd2e * qtmp*q[j]*rinv; + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) + ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv; + else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } + } else evdwl = 0.0; + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulCutOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCutCoulCut::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.h b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h new file mode 100644 index 0000000000..c8c34e2591 --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cut/coul/cut/omp,PairLJCutCoulCutOMP) + +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H +#define LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H + +#include "pair_lj_cut_coul_cut.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulCutOMP : public PairLJCutCoulCut, public ThrOMP { + + public: + PairLJCutCoulCutOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp new file mode 100644 index 0000000000..13a4a1906f --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp @@ -0,0 +1,186 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_cut_coul_debye_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulDebyeOMP::PairLJCutCoulDebyeOMP(LAMMPS *lmp) : + PairLJCutCoulDebye(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulDebyeOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCutCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double r,rinv,screening; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + + if (rsq < cut_coulsq[itype][jtype]) { + r = sqrt(rsq); + rinv = 1.0/r; + screening = exp(-kappa*r); + forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv); + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq[itype][jtype]) + ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening; + else ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + } + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulDebyeOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCutCoulDebye::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h new file mode 100644 index 0000000000..00cf540be2 --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cut/coul/debye/omp,PairLJCutCoulDebyeOMP) + +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H +#define LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H + +#include "pair_lj_cut_coul_debye.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulDebyeOMP : public PairLJCutCoulDebye, public ThrOMP { + + public: + PairLJCutCoulDebyeOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp new file mode 100644 index 0000000000..1d8f977c96 --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp @@ -0,0 +1,220 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_cut_coul_long_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) : + PairLJCutCoulLong(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCutCoulLongOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype,itable; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double fraction,table; + double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = qtmp*q[j] * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulLongOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCutCoulLong::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_omp.h new file mode 100644 index 0000000000..ac408ba886 --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP) + +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H +#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H + +#include "pair_lj_cut_coul_long.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP { + + public: + PairLJCutCoulLongOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp new file mode 100644 index 0000000000..6ada944c53 --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp @@ -0,0 +1,462 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_cut_coul_long_tip4p_omp.h" +#include "atom.h" +#include "domain.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "error.h" +#include "memory.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulLongTIP4POMP::PairLJCutCoulLongTIP4POMP(LAMMPS *lmp) : + PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + + // for caching m-shift corrected positions + maxmpos = 0; + h1idx = h2idx = NULL; + mpos = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulLongTIP4POMP::~PairLJCutCoulLongTIP4POMP() +{ + memory->destroy(h1idx); + memory->destroy(h2idx); + memory->destroy(mpos); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nlocal = atom->nlocal; + const int nall = nlocal + atom->nghost; + + // reallocate per-atom arrays, if necessary + if (nall > maxmpos) { + maxmpos = nall; + memory->grow(mpos,maxmpos,3,"pair:mpos"); + memory->grow(h1idx,maxmpos,"pair:h1idx"); + memory->grow(h2idx,maxmpos,"pair:h2idx"); + } + + // cache corrected M positions in mpos[] + double **x = atom->x; + int *type = atom->type; + for (int i = 0; i < nlocal; i++) { + if (type[i] == typeO) { + find_M(i,h1idx[i],h2idx[i],mpos[i]); + } else { + mpos[i][0] = x[i][0]; + mpos[i][1] = x[i][1]; + mpos[i][2] = x[i][2]; + } + } + for (int i = nlocal; i < nall; i++) { + if (type[i] == typeO) { + find_M_permissive(i,h1idx[i],h2idx[i],mpos[i]); + } else { + mpos[i][0] = x[i][0]; + mpos[i][1] = x[i][1]; + mpos[i][2] = x[i][2]; + } + } + + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (vflag) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (vflag) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCutCoulLongTIP4POMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype,itable; + int n,vlist[6]; + int iH1,iH2,jH1,jH2; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul; + double fraction,table; + double delxOM,delyOM,delzOM; + double r,rsq,r2inv,r6inv,forcecoul,forcelj,cforce; + double factor_coul,factor_lj; + double grij,expm2,prefactor,t,erfc,ddotf; + double v[6],xH1[3],xH2[3]; + double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz; + double *x1,*x2; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + x1 = mpos[i]; + iH1 = h1idx[i]; + iH2 = h2idx[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + if (rsq < cut_ljsq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= factor_lj * r2inv; + + fxtmp += delx*forcelj; + fytmp += dely*forcelj; + fztmp += delz*forcelj; + f[j][0] -= delx*forcelj; + f[j][1] -= dely*forcelj; + f[j][2] -= delz*forcelj; + + if (EFLAG) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - + offset[itype][jtype]; + evdwl *= factor_lj; + } else evdwl = 0.0; + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1, + evdwl,0.0,forcelj,delx,dely,delz,tid); + } + + // adjust rsq and delxyz for off-site O charge(s) + + if (itype == typeO || jtype == typeO) { + x2 = mpos[j]; + jH1 = h1idx[j]; + jH2 = h2idx[j]; + if (jtype == typeO && ( jH1 < 0 || jH2 < 0 )) + error->one(FLERR,"TIP4P hydrogen is missing"); + delx = x1[0] - x2[0]; + dely = x1[1] - x2[1]; + delz = x1[2] - x2[2]; + rsq = delx*delx + dely*dely + delz*delz; + } + + // test current rsq against cutoff and compute Coulombic force + + if (rsq < cut_coulsq) { + r2inv = 1 / rsq; + if (!ncoultablebits || rsq <= tabinnersq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) { + forcecoul -= (1.0-factor_coul)*prefactor; + } + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & ncoulmask; + itable >>= ncoulshiftbits; + fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; + table = ftable[itable] + fraction*dftable[itable]; + forcecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + table = ctable[itable] + fraction*dctable[itable]; + prefactor = qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + } + + cforce = forcecoul * r2inv; + + // if i,j are not O atoms, force is applied directly + // if i or j are O atoms, force is on fictitious atom & partitioned + // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999) + // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f + // preserves total force and torque on water molecule + // virial = sum(r x F) where each water's atoms are near xi and xj + // vlist stores 2,4,6 atoms whose forces contribute to virial + + n = 0; + + if (itype != typeO) { + fxtmp += delx * cforce; + fytmp += dely * cforce; + fztmp += delz * cforce; + + if (VFLAG) { + v[0] = x[i][0] * delx * cforce; + v[1] = x[i][1] * dely * cforce; + v[2] = x[i][2] * delz * cforce; + v[3] = x[i][0] * dely * cforce; + v[4] = x[i][0] * delz * cforce; + v[5] = x[i][1] * delz * cforce; + vlist[n++] = i; + } + + } else { + + fdx = delx*cforce; + fdy = dely*cforce; + fdz = delz*cforce; + + delxOM = x[i][0] - x1[0]; + delyOM = x[i][1] - x1[1]; + delzOM = x[i][2] - x1[2]; + + ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) / + (qdist*qdist); + + f1x = alpha * (fdx - ddotf * delxOM); + f1y = alpha * (fdy - ddotf * delyOM); + f1z = alpha * (fdz - ddotf * delzOM); + + fOx = fdx - f1x; + fOy = fdy - f1y; + fOz = fdz - f1z; + + fHx = 0.5 * f1x; + fHy = 0.5 * f1y; + fHz = 0.5 * f1z; + + fxtmp += fOx; + fytmp += fOy; + fztmp += fOz; + + f[iH1][0] += fHx; + f[iH1][1] += fHy; + f[iH1][2] += fHz; + + f[iH2][0] += fHx; + f[iH2][1] += fHy; + f[iH2][2] += fHz; + + if (VFLAG) { + domain->closest_image(x[i],x[iH1],xH1); + domain->closest_image(x[i],x[iH2],xH2); + + v[0] = x[i][0]*fOx + xH1[0]*fHx + xH2[0]*fHx; + v[1] = x[i][1]*fOy + xH1[1]*fHy + xH2[1]*fHy; + v[2] = x[i][2]*fOz + xH1[2]*fHz + xH2[2]*fHz; + v[3] = x[i][0]*fOy + xH1[0]*fHy + xH2[0]*fHy; + v[4] = x[i][0]*fOz + xH1[0]*fHz + xH2[0]*fHz; + v[5] = x[i][1]*fOz + xH1[1]*fHz + xH2[1]*fHz; + + vlist[n++] = i; + vlist[n++] = iH1; + vlist[n++] = iH2; + } + } + + if (jtype != typeO) { + f[j][0] -= delx * cforce; + f[j][1] -= dely * cforce; + f[j][2] -= delz * cforce; + + if (VFLAG) { + v[0] -= x[j][0] * delx * cforce; + v[1] -= x[j][1] * dely * cforce; + v[2] -= x[j][2] * delz * cforce; + v[3] -= x[j][0] * dely * cforce; + v[4] -= x[j][0] * delz * cforce; + v[5] -= x[j][1] * delz * cforce; + vlist[n++] = j; + } + + } else { + + fdx = -delx*cforce; + fdy = -dely*cforce; + fdz = -delz*cforce; + + delxOM = x[j][0] - x2[0]; + delyOM = x[j][1] - x2[1]; + delzOM = x[j][2] - x2[2]; + + ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) / + (qdist*qdist); + + f1x = alpha * (fdx - ddotf * delxOM); + f1y = alpha * (fdy - ddotf * delyOM); + f1z = alpha * (fdz - ddotf * delzOM); + + fOx = fdx - f1x; + fOy = fdy - f1y; + fOz = fdz - f1z; + + fHx = 0.5 * f1x; + fHy = 0.5 * f1y; + fHz = 0.5 * f1z; + + f[j][0] += fOx; + f[j][1] += fOy; + f[j][2] += fOz; + + f[jH1][0] += fHx; + f[jH1][1] += fHy; + f[jH1][2] += fHz; + + f[jH2][0] += fHx; + f[jH2][1] += fHy; + f[jH2][2] += fHz; + + if (VFLAG) { + domain->closest_image(x[j],x[jH1],xH1); + domain->closest_image(x[j],x[jH2],xH2); + + v[0] += x[j][0]*fOx + xH1[0]*fHx + xH2[0]*fHx; + v[1] += x[j][1]*fOy + xH1[1]*fHy + xH2[1]*fHy; + v[2] += x[j][2]*fOz + xH1[2]*fHz + xH2[2]*fHz; + v[3] += x[j][0]*fOy + xH1[0]*fHy + xH2[0]*fHy; + v[4] += x[j][0]*fOz + xH1[0]*fHz + xH2[0]*fHz; + v[5] += x[j][1]*fOz + xH1[1]*fHz + xH2[1]*fHz; + + vlist[n++] = j; + vlist[n++] = jH1; + vlist[n++] = jH2; + } + } + + if (EFLAG) { + if (!ncoultablebits || rsq <= tabinnersq) + ecoul = prefactor*erfc; + else { + table = etable[itable] + fraction*detable[itable]; + ecoul = qtmp*q[j] * table; + } + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + } else ecoul = 0.0; + + if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,tid); + } + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongTIP4POMP::find_M_permissive(int i, int &iH1, int &iH2, double *xM) +{ + // test that O is correctly bonded to 2 succesive H atoms + + iH1 = atom->map(atom->tag[i] + 1); + iH2 = atom->map(atom->tag[i] + 2); + + if (iH1 == -1 || iH2 == -1) + return; + else + find_M(i,iH1,iH2,xM); +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulLongTIP4POMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJCutCoulLongTIP4P::memory_usage(); + bytes += 2 * maxmpos * sizeof(int); + bytes += 3 * maxmpos * sizeof(double); + bytes += maxmpos * sizeof(double *); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h new file mode 100644 index 0000000000..093fc0216b --- /dev/null +++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cut/coul/long/tip4p/omp,PairLJCutCoulLongTIP4POMP) + +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H +#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H + +#include "pair_lj_cut_coul_long_tip4p.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulLongTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP { + + public: + PairLJCutCoulLongTIP4POMP(class LAMMPS *); + virtual ~PairLJCutCoulLongTIP4POMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + + // this is to cache m-shift corrected positions. + int maxmpos; // size of the following arrays + int *h1idx, *h2idx; // local index of hydrogen atoms + double **mpos; // coordinates corrected for m-shift. + void find_M_permissive(int, int &, int &, double *); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_omp.cpp index 8ed82c5e5b..3d82149fec 100644 --- a/src/USER-OMP/pair_lj_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_omp.cpp @@ -19,9 +19,6 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" -#include "neigh_request.h" -#include "memory.h" -#include "error.h" using namespace LAMMPS_NS; @@ -69,7 +66,7 @@ void PairLJCutOMP::compute(int eflag, int vflag) } // reduce per thread forces into global force array. - force_reduce_thr(&(atom->f[0][0]), nall, nthreads, tid); + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); } // end of omp parallel region // reduce per thread energy and virial, if requested. diff --git a/src/USER-OMP/pair_lj_expand_omp.cpp b/src/USER-OMP/pair_lj_expand_omp.cpp new file mode 100644 index 0000000000..7b06503ee4 --- /dev/null +++ b/src/USER-OMP/pair_lj_expand_omp.cpp @@ -0,0 +1,164 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_expand_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJExpandOMP::PairLJExpandOMP(LAMMPS *lmp) : + PairLJExpand(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJExpandOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJExpandOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,forcelj,factor_lj; + double r,rshift,rshiftsq; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + r = sqrt(rsq); + rshift = r - shift[itype][jtype]; + rshiftsq = rshift*rshift; + r2inv = 1.0/rshiftsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = factor_lj*forcelj/rshift/r; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) + - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJExpandOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJExpand::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_expand_omp.h b/src/USER-OMP/pair_lj_expand_omp.h new file mode 100644 index 0000000000..29488deae8 --- /dev/null +++ b/src/USER-OMP/pair_lj_expand_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/cut/omp,PairLJExpandOMP) + +#else + +#ifndef LMP_PAIR_LJ_EXPAND_OMP_H +#define LMP_PAIR_LJ_EXPAND_OMP_H + +#include "pair_lj_expand.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJExpandOMP : public PairLJExpand, public ThrOMP { + + public: + PairLJExpandOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp new file mode 100644 index 0000000000..2e97fa1b5e --- /dev/null +++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp @@ -0,0 +1,210 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_gromacs_coul_gromacs_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJGromacsCoulGromacsOMP::PairLJGromacsCoulGromacsOMP(LAMMPS *lmp) : + PairLJGromacsCoulGromacs(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJGromacsCoulGromacsOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJGromacsCoulGromacsOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj; + double r,tlj,tc,fswitch,fswitchcoul,eswitch,ecoulswitch; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++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]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + 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; + + // skip if qi or qj = 0.0 since this potential may be used as + // coarse-grain model with many uncharged atoms + + if (rsq < cut_coulsq && qtmp != 0.0 && q[j] != 0.0) { + forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); + if (rsq > cut_coul_innersq) { + r = sqrt(rsq); + tc = r - cut_coul_inner; + fswitchcoul = qqrd2e * qtmp*q[j]*r*tc*tc*(coulsw1 + coulsw2*tc); + forcecoul += fswitchcoul; + } + forcecoul *= factor_coul; + } else forcecoul = 0.0; + + if (rsq < cut_ljsq) { + r6inv = r2inv*r2inv*r2inv; + jtype = type[j]; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + if (rsq > cut_lj_innersq) { + r = sqrt(rsq); + tlj = r - cut_lj_inner; + fswitch = r*tlj*tlj*(ljsw1[itype][jtype] + + ljsw2[itype][jtype]*tlj); + forcelj += fswitch; + } + forcelj *= factor_lj; + } else forcelj = 0.0; + + fpair = (forcecoul + forcelj) * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_coulsq) { + ecoul = qqrd2e * qtmp*q[j] * (sqrt(r2inv) - coulsw5); + if (rsq > cut_coul_innersq) { + ecoulswitch = tc*tc*tc * (coulsw3 + coulsw4*tc); + ecoul += qqrd2e*qtmp*q[j]*ecoulswitch; + } + ecoul *= factor_coul; + } else ecoul = 0.0; + if (rsq < cut_ljsq) { + evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + evdwl += ljsw5[itype][jtype]; + if (rsq > cut_lj_innersq) { + eswitch = tlj*tlj*tlj * + (ljsw3[itype][jtype] + ljsw4[itype][jtype]*tlj); + evdwl += eswitch; + } + evdwl *= factor_lj; + } else evdwl = 0.0; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,ecoul,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJGromacsCoulGromacsOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJGromacsCoulGromacs::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h new file mode 100644 index 0000000000..d789bd6797 --- /dev/null +++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/gromacs/coul/gromacs/omp,PairLJGromacsCoulGromacsOMP) + +#else + +#ifndef LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H +#define LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H + +#include "pair_lj_gromacs_coul_gromacs.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJGromacsCoulGromacsOMP : public PairLJGromacsCoulGromacs, public ThrOMP { + + public: + PairLJGromacsCoulGromacsOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_omp.cpp new file mode 100644 index 0000000000..f1c7d2faf9 --- /dev/null +++ b/src/USER-OMP/pair_lj_gromacs_omp.cpp @@ -0,0 +1,172 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_gromacs_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJGromacsOMP::PairLJGromacsOMP(LAMMPS *lmp) : + PairLJGromacs(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJGromacsOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJGromacsOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,forcelj,factor_lj; + double r,t,fswitch,eswitch; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + if (rsq > cut_inner_sq[itype][jtype]) { + r = sqrt(rsq); + t = r - cut_inner[itype][jtype]; + fswitch = r*t*t*(ljsw1[itype][jtype] + ljsw2[itype][jtype]*t); + forcelj += fswitch; + } + + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); + evdwl += ljsw5[itype][jtype]; + if (rsq > cut_inner_sq[itype][jtype]) { + eswitch = t*t*t*(ljsw3[itype][jtype] + ljsw4[itype][jtype]*t); + evdwl += eswitch; + } + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJGromacsOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJGromacs::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_omp.h new file mode 100644 index 0000000000..d192a414ef --- /dev/null +++ b/src/USER-OMP/pair_lj_gromacs_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/gromacs/omp,PairLJGromacsOMP) + +#else + +#ifndef LMP_PAIR_LJ_GROMACS_OMP_H +#define LMP_PAIR_LJ_GROMACS_OMP_H + +#include "pair_lj_gromacs.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJGromacsOMP : public PairLJGromacs, public ThrOMP { + + public: + PairLJGromacsOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_sf_omp.cpp b/src/USER-OMP/pair_lj_sf_omp.cpp new file mode 100644 index 0000000000..55ee908e47 --- /dev/null +++ b/src/USER-OMP/pair_lj_sf_omp.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_sf_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJShiftedForceOMP::PairLJShiftedForceOMP(LAMMPS *lmp) : + PairLJShiftedForce(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJShiftedForceOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJShiftedForceOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double t,rsq,r2inv,r6inv,forcelj,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r6inv = r2inv*r2inv*r2inv; + t = sqrt(r2inv*cutsq[itype][jtype]); + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) - + t*foffset[itype][jtype]; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) + + (t-1.0)*foffset[itype][jtype] - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJShiftedForceOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJShiftedForce::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_sf_omp.h b/src/USER-OMP/pair_lj_sf_omp.h new file mode 100644 index 0000000000..6fba43fb8f --- /dev/null +++ b/src/USER-OMP/pair_lj_sf_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/sf/omp,PairLJShiftedForceOMP) + +#else + +#ifndef LMP_PAIR_LJ_SF_OMP_H +#define LMP_PAIR_LJ_SF_OMP_H + +#include "pair_lj_sf.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJShiftedForceOMP : public PairLJShiftedForce, public ThrOMP { + + public: + PairLJShiftedForceOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lj_smooth_omp.cpp b/src/USER-OMP/pair_lj_smooth_omp.cpp new file mode 100644 index 0000000000..1ad88044a6 --- /dev/null +++ b/src/USER-OMP/pair_lj_smooth_omp.cpp @@ -0,0 +1,176 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lj_smooth_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairLJSmoothOMP::PairLJSmoothOMP(LAMMPS *lmp) : + PairLJSmooth(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairLJSmoothOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLJSmoothOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,forcelj,factor_lj; + double r,t,tsq,fskin; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + if (rsq < cut_inner_sq[itype][jtype]) { + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv-lj2[itype][jtype]); + } else { + r = sqrt(rsq); + t = r - cut_inner[itype][jtype]; + tsq = t*t; + fskin = ljsw1[itype][jtype] + ljsw2[itype][jtype]*t + + ljsw3[itype][jtype]*tsq + ljsw4[itype][jtype]*tsq*t; + forcelj = fskin*r; + } + + fpair = factor_lj*forcelj*r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (rsq < cut_inner_sq[itype][jtype]) + evdwl = r6inv * (lj3[itype][jtype]*r6inv - + lj4[itype][jtype]) - offset[itype][jtype]; + else + evdwl = ljsw0[itype][jtype] - ljsw1[itype][jtype]*t - + ljsw2[itype][jtype]*tsq/2.0 - ljsw3[itype][jtype]*tsq*t/3.0 - + ljsw4[itype][jtype]*tsq*tsq/4.0 - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLJSmoothOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLJSmooth::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lj_smooth_omp.h b/src/USER-OMP/pair_lj_smooth_omp.h new file mode 100644 index 0000000000..de27a4008d --- /dev/null +++ b/src/USER-OMP/pair_lj_smooth_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/smooth/omp,PairLJSmoothOMP) + +#else + +#ifndef LMP_PAIR_LJ_SMOOTH_OMP_H +#define LMP_PAIR_LJ_SMOOTH_OMP_H + +#include "pair_lj_smooth.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLJSmoothOMP : public PairLJSmooth, public ThrOMP { + + public: + PairLJSmoothOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_lubricate_omp.cpp b/src/USER-OMP/pair_lubricate_omp.cpp new file mode 100644 index 0000000000..d45e0bf1b6 --- /dev/null +++ b/src/USER-OMP/pair_lubricate_omp.cpp @@ -0,0 +1,328 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_lubricate_omp.h" +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "update.h" +#include "neighbor.h" +#include "random_mars.h" +#include "neigh_list.h" + +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +/* ---------------------------------------------------------------------- */ + +PairLubricateOMP::PairLubricateOMP(LAMMPS *lmp) : + PairLubricate(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; + random_thr = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairLubricateOMP::~PairLubricateOMP() +{ + if (random_thr) { + for (int i=1; i < comm->nthreads; ++i) + delete random_thr[i]; + + delete[] random_thr; + random_thr = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLubricateOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + if (!random_thr) + random_thr = new RanMars*[nthreads]; + + random_thr[0] = random; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (random_thr && tid > 0) + random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me + + comm->nprocs*tid); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid); + else eval<1,1,0>(f, torque, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid); + else eval<1,0,0>(f, torque, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid); + else eval<0,0,0>(f, torque, ifrom, ito, tid); + } + + // reduce per thread forces and torques into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairLubricateOMP::eval(double **f, double **torque, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz; + double rsq,r,h_sep,radi,tfmag; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3; + double vt1,vt2,vt3,w1,w2,w3,v_shear1,v_shear2,v_shear3; + double omega_t_1,omega_t_2,omega_t_3; + double n_cross_omega_t_1,n_cross_omega_t_2,n_cross_omega_t_3; + double wr1,wr2,wr3,wnnr,wn1,wn2,wn3; + double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3; + double a_squeeze,a_shear,a_pump,a_twist; + int *ilist,*jlist,*numneigh,**firstneigh; + + double **x = atom->x; + double **v = atom->v; + double **omega = atom->omega; + double *radius = atom->radius; + int *type = atom->type; + int nlocal = atom->nlocal; + double vxmu2f = force->vxmu2f; + RanMars &rng = *random_thr[tid]; + + double prethermostat = sqrt(2.0 * force->boltz * t_target / update->dt); + prethermostat *= sqrt(force->vxmu2f/force->ftm2v/force->mvv2e); + + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + a_squeeze = a_shear = a_pump = a_twist = 0.0; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + 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]) { + + r = sqrt(rsq); + + // relative translational velocity + + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component N.(v1-v2) = nn.(v1-v2) + + vnnr = vr1*delx + vr2*dely + vr3*delz; + vnnr /= r; + vn1 = delx*vnnr / r; + vn2 = dely*vnnr / r; + vn3 = delz*vnnr / r; + + // tangential component -P.(v1-v2) + // P = (I - nn) where n is vector between centers + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // additive rotational velocity = omega_1 + omega_2 + + w1 = omega[i][0] + omega[j][0]; + w2 = omega[i][1] + omega[j][1]; + w3 = omega[i][2] + omega[j][2]; + + // relative velocities n X P . (v1-v2) = n X (I-nn) . (v1-v2) + + v_shear1 = (dely*vt3 - delz*vt2) / r; + v_shear2 = -(delx*vt3 - delz*vt1) / r; + v_shear3 = (delx*vt2 - dely*vt1) / r; + + // relative rotation rate P.(omega1 + omega2) + + omega_t_1 = w1 - delx*(delx*w1) / rsq; + omega_t_2 = w2 - dely*(dely*w2) / rsq; + omega_t_3 = w3 - delz*(delz*w3) / rsq; + + // n X omega_t + + n_cross_omega_t_1 = (dely*omega_t_3 - delz*omega_t_2) / r; + n_cross_omega_t_2 = -(delx*omega_t_3 - delz*omega_t_1) / r; + n_cross_omega_t_3 = (delx*omega_t_2 - dely*omega_t_1) / r; + + // N.(w1-w2) and P.(w1-w2) + + wr1 = omega[i][0] - omega[j][0]; + wr2 = omega[i][1] - omega[j][1]; + wr3 = omega[i][2] - omega[j][2]; + + wnnr = wr1*delx + wr2*dely + wr3*delz; + wn1 = delx*wnnr / rsq; + wn2 = dely*wnnr / rsq; + wn3 = delz*wnnr / rsq; + + P_dot_wrel_1 = wr1 - delx*(delx*wr1)/rsq; + P_dot_wrel_2 = wr2 - dely*(dely*wr2)/rsq; + P_dot_wrel_3 = wr3 - delz*(delz*wr3)/rsq; + + // compute components of pair-hydro + + h_sep = r - 2.0*radi; + + if (flag1) + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); + if (flag2) + a_shear = (MY_PI*mu*2.*radi/2.0) * + log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0; + if (flag3) + a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) * + ((3.0/20.0) * log(2.0*radi/2.0/h_sep) + + (63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep)); + if (flag4) + a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) * + (h_sep/2.0/radi) * log(2.0/(2.0*h_sep)); + + if (h_sep >= cut_inner[itype][jtype]) { + fx = -a_squeeze*vn1 - a_shear*(2.0/r)*(2.0/r)*vt1 + + (2.0/r)*a_shear*n_cross_omega_t_1; + fy = -a_squeeze*vn2 - a_shear*(2.0/r)*(2.0/r)*vt2 + + (2.0/r)*a_shear*n_cross_omega_t_2; + fz = -a_squeeze*vn3 - a_shear*(2.0/r)*(2.0/r)*vt3 + + (2.0/r)*a_shear*n_cross_omega_t_3; + fx *= vxmu2f; + fy *= vxmu2f; + fz *= vxmu2f; + + // add in thermostat force + + tfmag = prethermostat*sqrt(a_squeeze)*(rng.uniform()-0.5); + fx -= tfmag * delx/r; + fy -= tfmag * dely/r; + fz -= tfmag * delz/r; + + tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 - + a_pump*P_dot_wrel_1 - a_twist*wn1; + ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 - + a_pump*P_dot_wrel_2 - a_twist*wn2; + tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 - + a_pump*P_dot_wrel_3 - a_twist*wn3; + torque[i][0] += vxmu2f * tx; + torque[i][1] += vxmu2f * ty; + torque[i][2] += vxmu2f * tz; + + } else { + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * + (2.0*radi/4.0/cut_inner[itype][jtype]); + fpair = -a_squeeze*vnnr; + fpair *= vxmu2f; + + // add in thermostat force + + fpair -= prethermostat*sqrt(a_squeeze)*(rng.uniform()-0.5); + + fx = fpair * delx/r; + fy = fpair * dely/r; + fz = fpair * delz/r; + } + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + + if (h_sep >= cut_inner[itype][jtype]) { + tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 + + a_pump*P_dot_wrel_1 + a_twist*wn1; + ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 + + a_pump*P_dot_wrel_2 + a_twist*wn2; + tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 + + a_pump*P_dot_wrel_3 + a_twist*wn3; + torque[j][0] += vxmu2f * tx; + torque[j][1] += vxmu2f * ty; + torque[j][2] += vxmu2f * tz; + } + } + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + 0.0,0.0,fx,fy,fz,delx,dely,delz,tid); + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairLubricateOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairLubricate::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_lubricate_omp.h b/src/USER-OMP/pair_lubricate_omp.h new file mode 100644 index 0000000000..d36d190463 --- /dev/null +++ b/src/USER-OMP/pair_lubricate_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lubricate/omp,PairLubricateOMP) + +#else + +#ifndef LMP_PAIR_LUBRICATE_OMP_H +#define LMP_PAIR_LUBRICATE_OMP_H + +#include "pair_lubricate.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairLubricateOMP : public PairLubricate, public ThrOMP { + + public: + PairLubricateOMP(class LAMMPS *); + virtual ~PairLubricateOMP(); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + class RanMars **random_thr; + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_morse_omp.cpp b/src/USER-OMP/pair_morse_omp.cpp new file mode 100644 index 0000000000..a53e35a977 --- /dev/null +++ b/src/USER-OMP/pair_morse_omp.cpp @@ -0,0 +1,160 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_morse_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairMorseOMP::PairMorseOMP(LAMMPS *lmp) : + PairMorse(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairMorseOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairMorseOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,dr,dexp,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + r = sqrt(rsq); + dr = r - r0[itype][jtype]; + dexp = exp(-alpha[itype][jtype] * dr); + fpair = factor_lj * morse1[itype][jtype] * (dexp*dexp - dexp) / r; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = d0[itype][jtype] * (dexp*dexp - 2.0*dexp) - + offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairMorseOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairMorse::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_morse_omp.h b/src/USER-OMP/pair_morse_omp.h new file mode 100644 index 0000000000..a966e6f11f --- /dev/null +++ b/src/USER-OMP/pair_morse_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(morse/omp,PairMorseOMP) + +#else + +#ifndef LMP_PAIR_MORSE_OMP_H +#define LMP_PAIR_MORSE_OMP_H + +#include "pair_morse.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairMorseOMP : public PairMorse, public ThrOMP { + + public: + PairMorseOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_peri_lps_omp.cpp b/src/USER-OMP/pair_peri_lps_omp.cpp new file mode 100644 index 0000000000..7cb1e83086 --- /dev/null +++ b/src/USER-OMP/pair_peri_lps_omp.cpp @@ -0,0 +1,456 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "float.h" +#include "pair_peri_lps_omp.h" +#include "fix.h" +#include "fix_peri_neigh.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "force.h" +#include "memory.h" +#include "lattice.h" +#include "modify.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairPeriLPSOMP::PairPeriLPSOMP(LAMMPS *lmp) : + PairPeriLPS(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairPeriLPSOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow bond forces array if necessary + + if (atom->nmax > nmax) { + memory->destroy(s0_new); + memory->destroy(theta); + nmax = atom->nmax; + memory->create(s0_new,nmax,"pair:s0_new"); + memory->create(theta,nmax,"pair:theta"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairPeriLPSOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz; + double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0; + double rsq,r,dr,rk,evdwl,fpair,fbond; + int *ilist,*jlist,*numneigh,**firstneigh; + double d_ij,delta,stretch; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double fxtmp,fytmp,fztmp; + + double *vfrac = atom->vfrac; + double *s0 = atom->s0; + double **x0 = atom->x0; + double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0; + int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner; + int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner; + double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume; + + // lc = lattice constant + // init_style guarantees it's the same in x, y, and z + + double lc = domain->lattice->xlattice; + double half_lc = 0.5*lc; + double vfrac_scale = 1.0; + + // short-range forces + + int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic); + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + // need minimg() for x0 difference since not ghosted + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + xtmp0 = x0[i][0]; + ytmp0 = x0[i][1]; + ztmp0 = x0[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + + rsq = delx*delx + dely*dely + delz*delz; + delx0 = xtmp0 - x0[j][0]; + dely0 = ytmp0 - x0[j][1]; + delz0 = ztmp0 - x0[j][2]; + if (periodic) domain->minimum_image(delx0,dely0,delz0); + rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0; + jtype = type[j]; + + r = sqrt(rsq); + + // short-range interaction distance based on initial particle position + // 0.9 and 1.35 are constants + + d_ij = MIN(0.9*sqrt(rsq0),1.35*lc); + + // short-range contact forces + // 15 is constant taken from the EMU Theory Manual + // Silling, 12 May 2005, p 18 + + if (r < d_ij) { + dr = r - d_ij; + + // kshort based upon short-range force constant + // of the bond-based theory used in PMB model + + double kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) / + (3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]); + rk = (kshort * vfrac[j]) * (dr / cut[itype][jtype]); + + if (r > 0.0) fpair = -(rk/r); + else fpair = 0.0; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) evdwl = 0.5*rk*dr; + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0, + fpair*vfrac[i],delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } + + // wait until all threads are done since we + // need to distribute the work differently. + sync_threads(); + +#if defined(_OPENMP) + // each thread works on a fixed chunk of atoms. + const int idelta = 1 + nlocal/comm->nthreads; + iifrom = tid*idelta; + iito = iifrom + idelta; + if (iito > nlocal) + iito = nlocal; +#else + iifrom = 0; + iito = nlocal; +#endif + + // Compute the dilatation on each particle + compute_dilatation_thr(iifrom, iito); + + // wait until all threads are done before communication + sync_threads(); + +#if defined(_OPENMP) +#pragma omp master +#endif + { // communicate dilatation (theta) of each particle + comm->forward_comm_pair(this); + // communicate wighted volume (wvolume) upon every reneighbor + if (neighbor->ago == 0) + comm->forward_comm_fix(modify->fix[ifix_peri]); + } + + sync_threads(); + + // Volume-dependent part of the energy + if (EFLAG) { + for (i = iifrom; i < iito; i++) { + itype = type[i]; + if (eflag_global) + eng_vdwl_thr[tid] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]); + if (eflag_atom) + eatom_thr[tid][i] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]); + } + } + + // loop over my particles and their partners + // partner list contains all bond partners, so I-J appears twice + // if bond already broken, skip this partner + // first = true if this is first neighbor of particle i + + bool first; + double omega_minus, omega_plus; + + for (i = iifrom; i < iito; ++i) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + xtmp0 = x0[i][0]; + ytmp0 = x0[i][1]; + ztmp0 = x0[i][2]; + itype = type[i]; + jnum = npartner[i]; + first = true; + + for (jj = 0; jj < jnum; jj++) { + if (partner[i][jj] == 0) continue; + j = atom->map(partner[i][jj]); + + // check if lost a partner without first breaking bond + + if (j < 0) { + partner[i][jj] = 0; + continue; + } + + // compute force density, add to PD equation of motion + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + if (periodic) domain->minimum_image(delx,dely,delz); + rsq = delx*delx + dely*dely + delz*delz; + delx0 = xtmp0 - x0[j][0]; + dely0 = ytmp0 - x0[j][1]; + delz0 = ztmp0 - x0[j][2]; + if (periodic) domain->minimum_image(delx0,dely0,delz0); + jtype = type[j]; + delta = cut[itype][jtype]; + r = sqrt(rsq); + dr = r - r0[i][jj]; + + // avoid roundoff errors + + if (fabs(dr) < 2.2204e-016) dr = 0.0; + + // scale vfrac[j] if particle j near the horizon + + if ((fabs(r0[i][jj] - delta)) <= half_lc) + vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) + + (1.0 + ((delta - half_lc)/(2*half_lc) ) ); + else vfrac_scale = 1.0; + + omega_plus = influence_function(-1.0*delx0,-1.0*dely0,-1.0*delz0); + omega_minus = influence_function(delx0,dely0,delz0); + rk = ( (3.0 * bulkmodulus[itype][itype]) - + (5.0 * shearmodulus[itype][itype]) ) * vfrac[j] * vfrac_scale * + ( (omega_plus * theta[i] / wvolume[i]) + + ( omega_minus * theta[j] / wvolume[j] ) ) * r0[i][jj]; + rk += 15.0 * ( shearmodulus[itype][itype] * vfrac[j] * vfrac_scale ) * + ( (omega_plus / wvolume[i]) + (omega_minus / wvolume[j]) ) * dr; + + if (r > 0.0) fbond = -(rk/r); + else fbond = 0.0; + + f[i][0] += delx*fbond; + f[i][1] += dely*fbond; + f[i][2] += delz*fbond; + + // since I-J is double counted, set newton off & use 1/2 factor and I,I + + double deviatoric_extension = dr - (theta[i]* r0[i][jj] / 3.0); + if (EFLAG) evdwl = 0.5 * 15 * (shearmodulus[itype][itype]/wvolume[i]) * + omega_plus*(deviatoric_extension * deviatoric_extension) * + vfrac[j] * vfrac_scale; + if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0, + 0.5*fbond*vfrac[i],delx,dely,delz,tid); + + // find stretch in bond I-J and break if necessary + // use s0 from previous timestep + + stretch = dr / r0[i][jj]; + if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0; + + // update s0 for next timestep + + if (first) + s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch); + else + s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch)); + + first = false; + } + } + + sync_threads(); + + // store new s0 (in parallel) + for (i = iifrom; i < iito; i++) s0[i] = s0_new[i]; +} + +/* ---------------------------------------------------------------------- */ + +void PairPeriLPSOMP::compute_dilatation_thr(int ifrom, int ito) +{ + int i,j,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz; + double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0; + double rsq,r,dr; + double delta; + + double **x = atom->x; + int *type = atom->type; + double **x0 = atom->x0; + double *vfrac = atom->vfrac; + double vfrac_scale = 1.0; + + double lc = domain->lattice->xlattice; + double half_lc = 0.5*lc; + + double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0; + int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner; + int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner; + double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume; + + int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic; + + // compute the dilatation theta + + for (i = ifrom; i < ito; i++) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + xtmp0 = x0[i][0]; + ytmp0 = x0[i][1]; + ztmp0 = x0[i][2]; + jnum = npartner[i]; + theta[i] = 0.0; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + + // if bond already broken, skip this partner + if (partner[i][jj] == 0) continue; + + // Look up local index of this partner particle + j = atom->map(partner[i][jj]); + + // Skip if particle is "lost" + if (j < 0) continue; + + // Compute force density and add to PD equation of motion + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + if (periodic) domain->minimum_image(delx,dely,delz); + rsq = delx*delx + dely*dely + delz*delz; + delx0 = xtmp0 - x0[j][0]; + dely0 = ytmp0 - x0[j][1]; + delz0 = ztmp0 - x0[j][2]; + if (periodic) domain->minimum_image(delx0,dely0,delz0); + + r = sqrt(rsq); + dr = r - r0[i][jj]; + if (fabs(dr) < 2.2204e-016) dr = 0.0; + + jtype = type[j]; + delta = cut[itype][jtype]; + + // scale vfrac[j] if particle j near the horizon + + if ((fabs(r0[i][jj] - delta)) <= half_lc) + vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) + + (1.0 + ((delta - half_lc)/(2*half_lc) ) ); + else vfrac_scale = 1.0; + + theta[i] += influence_function(delx0, dely0, delz0) * r0[i][jj] * dr * + vfrac[j] * vfrac_scale; + } + + // if wvolume[i] is zero, then particle i has no bonds + // therefore, the dilatation is set to + + if (wvolume[i] != 0.0) theta[i] = (3.0/wvolume[i]) * theta[i]; + else theta[i] = 0; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairPeriLPSOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairPeriLPS::memory_usage(); + + return bytes; +} + diff --git a/src/USER-OMP/pair_peri_lps_omp.h b/src/USER-OMP/pair_peri_lps_omp.h new file mode 100644 index 0000000000..2068830ca0 --- /dev/null +++ b/src/USER-OMP/pair_peri_lps_omp.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(peri/lps/omp,PairPeriLPSOMP) + +#else + +#ifndef LMP_PAIR_PERI_LPS_OMP_H +#define LMP_PAIR_PERI_LPS_OMP_H + +#include "pair_peri_lps.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairPeriLPSOMP : public PairPeriLPS, public ThrOMP { + + public: + PairPeriLPSOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + protected: + void compute_dilatation_thr(int ifrom, int ito); + + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_peri_pmb_omp.cpp b/src/USER-OMP/pair_peri_pmb_omp.cpp new file mode 100644 index 0000000000..4e46d142d9 --- /dev/null +++ b/src/USER-OMP/pair_peri_pmb_omp.cpp @@ -0,0 +1,312 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "float.h" +#include "pair_peri_pmb_omp.h" +#include "fix.h" +#include "fix_peri_neigh.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "force.h" +#include "memory.h" +#include "lattice.h" +#include "modify.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairPeriPMBOMP::PairPeriPMBOMP(LAMMPS *lmp) : + PairPeriPMB(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairPeriPMBOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + + // grow bond forces array if necessary + + if (atom->nmax > nmax) { + memory->destroy(s0_new); + nmax = atom->nmax; + memory->create(s0_new,nmax,"pair:s0_new"); + } + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairPeriPMBOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz; + double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0; + double rsq,r,dr,rk,evdwl,fpair,fbond; + int *ilist,*jlist,*numneigh,**firstneigh; + double d_ij,delta,stretch; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double fxtmp,fytmp,fztmp; + + double *vfrac = atom->vfrac; + double *s0 = atom->s0; + double **x0 = atom->x0; + double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0; + int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner; + int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner; + + // lc = lattice constant + // init_style guarantees it's the same in x, y, and z + + double lc = domain->lattice->xlattice; + double half_lc = 0.5*lc; + double vfrac_scale = 1.0; + + // short-range forces + + int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic); + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + // need minimg() for x0 difference since not ghosted + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + xtmp0 = x0[i][0]; + ytmp0 = x0[i][1]; + ztmp0 = x0[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + delx0 = xtmp0 - x0[j][0]; + dely0 = ytmp0 - x0[j][1]; + delz0 = ztmp0 - x0[j][2]; + if (periodic) domain->minimum_image(delx0,dely0,delz0); + rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0; + jtype = type[j]; + + r = sqrt(rsq); + + // short-range interaction distance based on initial particle position + // 0.9 and 1.35 are constants + + d_ij = MIN(0.9*sqrt(rsq0),1.35*lc); + + // short-range contact forces + // 15 is constant taken from the EMU Theory Manual + // Silling, 12 May 2005, p 18 + + if (r < d_ij) { + dr = r - d_ij; + + rk = (15.0 * kspring[itype][jtype] * vfrac[j]) * + (dr / cut[itype][jtype]); + if (r > 0.0) fpair = -(rk/r); + else fpair = 0.0; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) evdwl = 0.5*rk*dr; + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0, + fpair*vfrac[i],delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } + + // wait until all threads are done since we + // need to distribute the work differently. + sync_threads(); + +#if defined(_OPENMP) + // each thread works on a fixed chunk of atoms. + const int idelta = 1 + nlocal/comm->nthreads; + iifrom = tid*idelta; + iito = iifrom + idelta; + if (iito > nlocal) + iito = nlocal; +#else + iifrom = 0; + iito = nlocal; +#endif + + // loop over my particles and their partners + // partner list contains all bond partners, so I-J appears twice + // if bond already broken, skip this partner + // first = true if this is first neighbor of particle i + + bool first; + + for (i = iifrom; i < iito; ++i) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jnum = npartner[i]; + s0_new[i] = DBL_MAX; + first = true; + + for (jj = 0; jj < jnum; jj++) { + if (partner[i][jj] == 0) continue; + j = atom->map(partner[i][jj]); + + // check if lost a partner without first breaking bond + + if (j < 0) { + partner[i][jj] = 0; + continue; + } + + // compute force density, add to PD equation of motion + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + if (periodic) domain->minimum_image(delx,dely,delz); + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + delta = cut[itype][jtype]; + r = sqrt(rsq); + dr = r - r0[i][jj]; + + // avoid roundoff errors + + if (fabs(dr) < 2.2204e-016) dr = 0.0; + + // scale vfrac[j] if particle j near the horizon + + if ((fabs(r0[i][jj] - delta)) <= half_lc) + vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) + + (1.0 + ((delta - half_lc)/(2*half_lc) ) ); + else vfrac_scale = 1.0; + + stretch = dr / r0[i][jj]; + rk = (kspring[itype][jtype] * vfrac[j]) * vfrac_scale * stretch; + if (r > 0.0) fbond = -(rk/r); + else fbond = 0.0; + + f[i][0] += delx*fbond; + f[i][1] += dely*fbond; + f[i][2] += delz*fbond; + + // since I-J is double counted, set newton off & use 1/2 factor and I,I + + if (EFLAG) evdwl = 0.5*rk*dr; + if (EVFLAG) + ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0, + 0.5*fbond*vfrac[i],delx,dely,delz,tid); + + // find stretch in bond I-J and break if necessary + // use s0 from previous timestep + + if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0; + + // update s0 for next timestep + + if (first) + s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch); + else + s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch)); + first = false; + } + } + + sync_threads(); + + // store new s0 + for (i = iifrom; i < iito; i++) s0[i] = s0_new[i]; +} + +/* ---------------------------------------------------------------------- */ + +double PairPeriPMBOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairPeriPMB::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_peri_pmb_omp.h b/src/USER-OMP/pair_peri_pmb_omp.h new file mode 100644 index 0000000000..9940e5ed15 --- /dev/null +++ b/src/USER-OMP/pair_peri_pmb_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(peri/pmb/omp,PairPeriPMBOMP) + +#else + +#ifndef LMP_PAIR_PERI_PMB_OMP_H +#define LMP_PAIR_PERI_PMB_OMP_H + +#include "pair_peri_pmb.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairPeriPMBOMP : public PairPeriPMB, public ThrOMP { + + public: + PairPeriPMBOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_rebo_omp.cpp b/src/USER-OMP/pair_rebo_omp.cpp new file mode 100644 index 0000000000..70b5c4e8ae --- /dev/null +++ b/src/USER-OMP/pair_rebo_omp.cpp @@ -0,0 +1,33 @@ +/* ---------------------------------------------------------------------- + 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 "pair_rebo_omp.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairREBOOMP::PairREBOOMP(LAMMPS *lmp) : PairAIREBOOMP(lmp) {} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairREBOOMP::settings(int narg, char **arg) +{ + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); + + cutlj = 0.0; + ljflag = torflag = 0; +} diff --git a/src/USER-OMP/pair_rebo_omp.h b/src/USER-OMP/pair_rebo_omp.h new file mode 100644 index 0000000000..4606e56ae1 --- /dev/null +++ b/src/USER-OMP/pair_rebo_omp.h @@ -0,0 +1,36 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(rebo/omp,PairREBOOMP) + +#else + +#ifndef LMP_PAIR_REBO_OMP_H +#define LMP_PAIR_REBO_OMP_H + +#include "pair_airebo_omp.h" + +namespace LAMMPS_NS { + +class PairREBOOMP : public PairAIREBOOMP { + public: + PairREBOOMP(class LAMMPS *); + virtual void settings(int, char **); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_resquared_omp.cpp b/src/USER-OMP/pair_resquared_omp.cpp new file mode 100644 index 0000000000..4870553050 --- /dev/null +++ b/src/USER-OMP/pair_resquared_omp.cpp @@ -0,0 +1,210 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_resquared_omp.h" +#include "math_extra.h" +#include "atom.h" +#include "comm.h" +#include "atom_vec_ellipsoid.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairRESquaredOMP::PairRESquaredOMP(LAMMPS *lmp) : + PairRESquared(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairRESquaredOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f, **torque; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + torque = atom->torque + tid*nall; + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid); + else eval<1,1,0>(f, torque, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid); + else eval<1,0,0>(f, torque, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid); + else eval<0,0,0>(f, torque, ifrom, ito, tid); + } + + // reduce per thread forces and torques into global arrays. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairRESquaredOMP::eval(double **f, double **tor, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj; + double fforce[3],ttor[3],rtor[3],r12[3]; + int *ilist,*jlist,*numneigh,**firstneigh; + RE2Vars wi,wj; + + double **x = atom->x; + int *ellipsoid = atom->ellipsoid; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + + double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itype = type[i]; + + // not a LJ sphere + + if (lshape[itype] != 0.0) precompute_i(i,wi); + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + // r12 = center to center vector + + r12[0] = x[j][0]-x[i][0]; + r12[1] = x[j][1]-x[i][1]; + r12[2] = x[j][2]-x[i][2]; + rsq = MathExtra::dot3(r12,r12); + jtype = type[j]; + + // compute if less than cutoff + + if (rsq < cutsq[itype][jtype]) { + switch (form[itype][jtype]) { + + case SPHERE_SPHERE: + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + forcelj *= -r2inv; + if (EFLAG) one_eng = + r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) - + offset[itype][jtype]; + fforce[0] = r12[0]*forcelj; + fforce[1] = r12[1]*forcelj; + fforce[2] = r12[2]*forcelj; + break; + + case SPHERE_ELLIPSE: + precompute_i(j,wj); + if (NEWTON_PAIR || j < nlocal) { + one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,true); + tor[j][0] += rtor[0]*factor_lj; + tor[j][1] += rtor[1]*factor_lj; + tor[j][2] += rtor[2]*factor_lj; + } else + one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,false); + break; + + case ELLIPSE_SPHERE: + one_eng = resquared_lj(i,j,wi,r12,rsq,fforce,ttor,true); + tor[i][0] += ttor[0]*factor_lj; + tor[i][1] += ttor[1]*factor_lj; + tor[i][2] += ttor[2]*factor_lj; + break; + + default: + precompute_i(j,wj); + one_eng = resquared_analytic(i,j,wi,wj,r12,rsq,fforce,ttor,rtor); + tor[i][0] += ttor[0]*factor_lj; + tor[i][1] += ttor[1]*factor_lj; + tor[i][2] += ttor[2]*factor_lj; + if (NEWTON_PAIR || j < nlocal) { + tor[j][0] += rtor[0]*factor_lj; + tor[j][1] += rtor[1]*factor_lj; + tor[j][2] += rtor[2]*factor_lj; + } + break; + } + + fforce[0] *= factor_lj; + fforce[1] *= factor_lj; + fforce[2] *= factor_lj; + f[i][0] += fforce[0]; + f[i][1] += fforce[1]; + f[i][2] += fforce[2]; + + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= fforce[0]; + f[j][1] -= fforce[1]; + f[j][2] -= fforce[2]; + } + + if (EFLAG) evdwl = factor_lj*one_eng; + + if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fforce[0],fforce[1],fforce[2], + -r12[0],-r12[1],-r12[2],tid); + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairRESquaredOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairRESquared::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_resquared_omp.h b/src/USER-OMP/pair_resquared_omp.h new file mode 100644 index 0000000000..2a50bb6dd0 --- /dev/null +++ b/src/USER-OMP/pair_resquared_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(resquared/omp,PairRESquaredOMP) + +#else + +#ifndef LMP_PAIR_RESQUARED_OMP_H +#define LMP_PAIR_RESQUARED_OMP_H + +#include "pair_resquared.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairRESquaredOMP : public PairRESquared, public ThrOMP { + + public: + PairRESquaredOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, double **torque, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp new file mode 100644 index 0000000000..7667efa983 --- /dev/null +++ b/src/USER-OMP/pair_soft_omp.cpp @@ -0,0 +1,160 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_soft_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +#define SMALL 1.0e-4 + +/* ---------------------------------------------------------------------- */ + +PairSoftOMP::PairSoftOMP(LAMMPS *lmp) : + PairSoft(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairSoftOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairSoftOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double r,rsq,arg,factor_lj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + r = sqrt(rsq); + arg = PI/cut[itype][jtype]; + if (r > SMALL) fpair = factor_lj * prefactor[itype][jtype] * + sin(arg*r) * arg/r; + else fpair = 0.0; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) + evdwl = factor_lj * prefactor[itype][jtype] * (1.0+cos(arg*r)); + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairSoftOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairSoft::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_soft_omp.h b/src/USER-OMP/pair_soft_omp.h new file mode 100644 index 0000000000..840d874601 --- /dev/null +++ b/src/USER-OMP/pair_soft_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(soft/omp,PairSoftOMP) + +#else + +#ifndef LMP_PAIR_SOFT_OMP_H +#define LMP_PAIR_SOFT_OMP_H + +#include "pair_soft.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairSoftOMP : public PairSoft, public ThrOMP { + + public: + PairSoftOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_sw_omp.cpp b/src/USER-OMP/pair_sw_omp.cpp new file mode 100644 index 0000000000..5d7f1a60d7 --- /dev/null +++ b/src/USER-OMP/pair_sw_omp.cpp @@ -0,0 +1,212 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_sw_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairSWOMP::PairSWOMP(LAMMPS *lmp) : + PairSW(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairSWOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + eval<1,1>(f, ifrom, ito, tid); + } else { + eval<1,0>(f, ifrom, ito, tid); + } + } else eval<0,0>(f, ifrom, ito, tid); + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairSWOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,ii,jj,kk,jnum,jnumm1,itag,jtag; + int itype,jtype,ktype,ijparam,ikparam,ijkparam; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,rsq1,rsq2; + double delr1[3],delr2[3],fj[3],fk[3]; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + double fxtmp,fytmp,fztmp; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itag = tag[i]; + itype = map[type[i]]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + fxtmp = fytmp = fztmp = 0.0; + + // two-body interactions, skip half of them + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + 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; + if (x[j][2] == ztmp && x[j][1] < ytmp) continue; + if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + + jtype = map[type[j]]; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + ijparam = elem2param[itype][jtype][jtype]; + if (rsq > params[ijparam].cutsq) continue; + + twobody(¶ms[ijparam],rsq,fpair,EFLAG,evdwl); + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + + jnumm1 = jnum - 1; + + for (jj = 0; jj < jnumm1; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = map[type[j]]; + ijparam = elem2param[itype][jtype][jtype]; + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; + if (rsq1 > params[ijparam].cutsq) continue; + + double fjxtmp,fjytmp,fjztmp; + fjxtmp = fjytmp = fjztmp = 0.0; + + for (kk = jj+1; kk < jnum; kk++) { + k = jlist[kk]; + k &= NEIGHMASK; + ktype = map[type[k]]; + ikparam = elem2param[itype][ktype][ktype]; + ijkparam = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; + if (rsq2 > params[ikparam].cutsq) continue; + + threebody(¶ms[ijparam],¶ms[ikparam],¶ms[ijkparam], + rsq1,rsq2,delr1,delr2,fj,fk,EFLAG,evdwl); + + fxtmp -= fj[0] + fk[0]; + fytmp -= fj[1] + fk[1]; + fztmp -= fj[2] + fk[2]; + fjxtmp += fj[0]; + fjytmp += fj[1]; + fjztmp += fj[2]; + f[k][0] += fk[0]; + f[k][1] += fk[1]; + f[k][2] += fk[2]; + + if (EVFLAG) ev_tally3_thr(this,i,j,k,evdwl,0.0,fj,fk,delr1,delr2,tid); + } + f[j][0] += fjxtmp; + f[j][1] += fjytmp; + f[j][2] += fjztmp; + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairSWOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairSW::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_sw_omp.h b/src/USER-OMP/pair_sw_omp.h new file mode 100644 index 0000000000..40052d7d41 --- /dev/null +++ b/src/USER-OMP/pair_sw_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(sw/omp,PairSWOMP) + +#else + +#ifndef LMP_PAIR_SW_OMP_H +#define LMP_PAIR_SW_OMP_H + +#include "pair_sw.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairSWOMP : public PairSW, public ThrOMP { + + public: + PairSWOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_table_omp.cpp b/src/USER-OMP/pair_table_omp.cpp new file mode 100644 index 0000000000..6b14d4c981 --- /dev/null +++ b/src/USER-OMP/pair_table_omp.cpp @@ -0,0 +1,202 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_table_omp.h" +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairTableOMP::PairTableOMP(LAMMPS *lmp) : + PairTable(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairTableOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairTableOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype,itable; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,factor_lj,fraction,value,a,b; + int *ilist,*jlist,*numneigh,**firstneigh; + Table *tb; + + union_int_float_t rsq_lookup; + int tlm1 = tablength - 1; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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]) { + tb = &tables[tabindex[itype][jtype]]; + if (rsq < tb->innersq) + error->one(FLERR,"Pair distance < table inner cutoff"); + + if (tabstyle == LOOKUP) { + itable = static_cast ((rsq - tb->innersq) * tb->invdelta); + if (itable >= tlm1) + error->one(FLERR,"Pair distance > table outer cutoff"); + fpair = factor_lj * tb->f[itable]; + } else if (tabstyle == LINEAR) { + itable = static_cast ((rsq - tb->innersq) * tb->invdelta); + if (itable >= tlm1) + error->one(FLERR,"Pair distance > table outer cutoff"); + fraction = (rsq - tb->rsq[itable]) * tb->invdelta; + value = tb->f[itable] + fraction*tb->df[itable]; + fpair = factor_lj * value; + } else if (tabstyle == SPLINE) { + itable = static_cast ((rsq - tb->innersq) * tb->invdelta); + if (itable >= tlm1) + error->one(FLERR,"Pair distance > table outer cutoff"); + b = (rsq - tb->rsq[itable]) * tb->invdelta; + a = 1.0 - b; + value = a * tb->f[itable] + b * tb->f[itable+1] + + ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * + tb->deltasq6; + fpair = factor_lj * value; + } else { + rsq_lookup.f = rsq; + itable = rsq_lookup.i & tb->nmask; + itable >>= tb->nshiftbits; + fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; + value = tb->f[itable] + fraction*tb->df[itable]; + fpair = factor_lj * value; + } + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + if (tabstyle == LOOKUP) + evdwl = tb->e[itable]; + else if (tabstyle == LINEAR || tabstyle == BITMAP) + evdwl = tb->e[itable] + fraction*tb->de[itable]; + else + evdwl = a * tb->e[itable] + b * tb->e[itable+1] + + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * + tb->deltasq6; + evdwl *= factor_lj; + } + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairTableOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairTable::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_table_omp.h b/src/USER-OMP/pair_table_omp.h new file mode 100644 index 0000000000..6fd1ce74a4 --- /dev/null +++ b/src/USER-OMP/pair_table_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(table/omp,PairTableOMP) + +#else + +#ifndef LMP_PAIR_TABLE_OMP_H +#define LMP_PAIR_TABLE_OMP_H + +#include "pair_table.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairTableOMP : public PairTable, public ThrOMP { + + public: + PairTableOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_tersoff_omp.cpp b/src/USER-OMP/pair_tersoff_omp.cpp new file mode 100644 index 0000000000..f59a8488f7 --- /dev/null +++ b/src/USER-OMP/pair_tersoff_omp.cpp @@ -0,0 +1,252 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_tersoff_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairTersoffOMP::PairTersoffOMP(LAMMPS *lmp) : + PairTersoff(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = vflag_atom = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else eval<0,0,0>(f, ifrom, ito, tid); + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairTersoffOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,k,ii,jj,kk,jnum; + int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,rsq1,rsq2; + double delr1[3],delr2[3],fi[3],fj[3],fk[3]; + double zeta_ij,prefactor; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + double fxtmp,fytmp,fztmp; + + // loop over full neighbor list of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + itag = tag[i]; + itype = map[type[i]]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + fxtmp = fytmp = fztmp = 0.0; + + // two-body interactions, skip half of them + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + 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; + if (x[j][2] == ztmp && x[j][1] < ytmp) continue; + if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + + jtype = map[type[j]]; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + iparam_ij = elem2param[itype][jtype][jtype]; + if (rsq > params[iparam_ij].cutsq) continue; + + repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl); + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + + // three-body interactions + // skip immediately if I-J is not within cutoff + double fjxtmp,fjytmp,fjztmp; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = map[type[j]]; + iparam_ij = elem2param[itype][jtype][jtype]; + + delr1[0] = x[j][0] - xtmp; + delr1[1] = x[j][1] - ytmp; + delr1[2] = x[j][2] - ztmp; + rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; + if (rsq1 > params[iparam_ij].cutsq) continue; + + // accumulate bondorder zeta for each i-j interaction via loop over k + + fjxtmp = fjytmp = fjztmp = 0.0; + zeta_ij = 0.0; + + for (kk = 0; kk < jnum; kk++) { + if (jj == kk) continue; + k = jlist[kk]; + k &= NEIGHMASK; + ktype = map[type[k]]; + iparam_ijk = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; + if (rsq2 > params[iparam_ijk].cutsq) continue; + + zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); + } + + // pairwise force due to zeta + + force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair,prefactor,EFLAG,evdwl); + + fxtmp += delr1[0]*fpair; + fytmp += delr1[1]*fpair; + fztmp += delr1[2]*fpair; + fjxtmp -= delr1[0]*fpair; + fjytmp -= delr1[1]*fpair; + fjztmp -= delr1[2]*fpair; + + if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0, + -fpair,-delr1[0],-delr1[1],-delr1[2],tid); + + // attractive term via loop over k + + for (kk = 0; kk < jnum; kk++) { + if (jj == kk) continue; + k = jlist[kk]; + k &= NEIGHMASK; + ktype = map[type[k]]; + iparam_ijk = elem2param[itype][jtype][ktype]; + + delr2[0] = x[k][0] - xtmp; + delr2[1] = x[k][1] - ytmp; + delr2[2] = x[k][2] - ztmp; + rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; + if (rsq2 > params[iparam_ijk].cutsq) continue; + + attractive(¶ms[iparam_ijk],prefactor, + rsq1,rsq2,delr1,delr2,fi,fj,fk); + + fxtmp += fi[0]; + fytmp += fi[1]; + fztmp += fi[2]; + fjxtmp += fj[0]; + fjytmp += fj[1]; + fjztmp += fj[2]; + f[k][0] += fk[0]; + f[k][1] += fk[1]; + f[k][2] += fk[2]; + + if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid); + } + f[j][0] += fjxtmp; + f[j][1] += fjytmp; + f[j][2] += fjztmp; + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairTersoffOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairTersoff::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_tersoff_omp.h b/src/USER-OMP/pair_tersoff_omp.h new file mode 100644 index 0000000000..5e5dc066d2 --- /dev/null +++ b/src/USER-OMP/pair_tersoff_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tersoff/omp,PairTersoffOMP) + +#else + +#ifndef LMP_PAIR_TERSOFF_OMP_H +#define LMP_PAIR_TERSOFF_OMP_H + +#include "pair_tersoff.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairTersoffOMP : public PairTersoff, public ThrOMP { + + public: + PairTersoffOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_tersoff_zbl_omp.cpp b/src/USER-OMP/pair_tersoff_zbl_omp.cpp new file mode 100644 index 0000000000..4265d84fb7 --- /dev/null +++ b/src/USER-OMP/pair_tersoff_zbl_omp.cpp @@ -0,0 +1,296 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Aidan Thompson (SNL) - original Tersoff implementation + David Farrell (NWU) - ZBL addition +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_tersoff_zbl_omp.h" +#include "atom.h" +#include "update.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "force.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +#include "math_const.h" +using namespace LAMMPS_NS; +using namespace MathConst; + +#define MAXLINE 1024 +#define DELTA 4 + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function +------------------------------------------------------------------------- */ + +static double F_fermi(const double r, const double expsc, const double cut) +{ + return 1.0 / (1.0 + exp(-expsc*(r-cut))); +} + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function derivative with respect to r +------------------------------------------------------------------------- */ + +static double F_fermi_d(const double r, const double expsc, const double cut) +{ + return expsc*exp(-expsc*(r-cut)) / pow(1.0 + exp(-expsc*(r-cut)),2.0); +} + +/* ---------------------------------------------------------------------- */ + +PairTersoffZBLOMP::PairTersoffZBLOMP(LAMMPS *lmp) : PairTersoffOMP(lmp) +{ + // hard-wired constants in metal or real units + // a0 = Bohr radius + // epsilon0 = permittivity of vacuum = q / energy-distance units + // e = unit charge + // 1 Kcal/mole = 0.043365121 eV + + if (strcmp(update->unit_style,"metal") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635; + global_e = 1.0; + } else if (strcmp(update->unit_style,"real") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635 * 0.043365121; + global_e = 1.0; + } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units"); +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffZBLOMP::read_file(char *file) +{ + int params_per_line = 21; + char **words = new char*[params_per_line+1]; + + delete [] params; + params = NULL; + nparams = 0; + + // open file on proc 0 + + FILE *fp; + if (comm->me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open Tersoff potential file %s",file); + error->one(FLERR,str); + } + } + + // read each line out of file, skipping blank lines or leading '#' + // store line of params if all 3 element tags are in element list + + int n,nwords,ielement,jelement,kelement; + char line[MAXLINE],*ptr; + int eof = 0; + + while (1) { + if (comm->me == 0) { + ptr = fgets(line,MAXLINE,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + // strip comment, skip line if blank + + if (ptr = strchr(line,'#')) *ptr = '\0'; + nwords = atom->count_words(line); + if (nwords == 0) continue; + + // concatenate additional lines until have params_per_line words + + while (nwords < params_per_line) { + n = strlen(line); + if (comm->me == 0) { + ptr = fgets(&line[n],MAXLINE-n,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + if (ptr = strchr(line,'#')) *ptr = '\0'; + nwords = atom->count_words(line); + } + + if (nwords != params_per_line) + error->all(FLERR,"Incorrect format in Tersoff potential file"); + + // words = ptrs to all words in line + + nwords = 0; + words[nwords++] = strtok(line," \t\n\r\f"); + while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue; + + // ielement,jelement,kelement = 1st args + // if all 3 args are in element list, then parse this line + // else skip to next line + + for (ielement = 0; ielement < nelements; ielement++) + if (strcmp(words[0],elements[ielement]) == 0) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (strcmp(words[1],elements[jelement]) == 0) break; + if (jelement == nelements) continue; + for (kelement = 0; kelement < nelements; kelement++) + if (strcmp(words[2],elements[kelement]) == 0) break; + if (kelement == nelements) continue; + + // load up parameter settings and error check their values + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), + "pair:params"); + } + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].kelement = kelement; + params[nparams].powerm = atof(words[3]); + params[nparams].gamma = atof(words[4]); + params[nparams].lam3 = atof(words[5]); + params[nparams].c = atof(words[6]); + params[nparams].d = atof(words[7]); + params[nparams].h = atof(words[8]); + params[nparams].powern = atof(words[9]); + params[nparams].beta = atof(words[10]); + params[nparams].lam2 = atof(words[11]); + params[nparams].bigb = atof(words[12]); + params[nparams].bigr = atof(words[13]); + params[nparams].bigd = atof(words[14]); + params[nparams].lam1 = atof(words[15]); + params[nparams].biga = atof(words[16]); + params[nparams].Z_i = atof(words[17]); + params[nparams].Z_j = atof(words[18]); + params[nparams].ZBLcut = atof(words[19]); + params[nparams].ZBLexpscale = atof(words[20]); + + // currently only allow m exponent of 1 or 3 + + params[nparams].powermint = int(params[nparams].powerm); + + if ( + params[nparams].lam3 < 0.0 || params[nparams].c < 0.0 || + params[nparams].d < 0.0 || params[nparams].powern < 0.0 || + params[nparams].beta < 0.0 || params[nparams].lam2 < 0.0 || + params[nparams].bigb < 0.0 || params[nparams].bigr < 0.0 || + params[nparams].bigd < 0.0 || + params[nparams].bigd > params[nparams].bigr || + params[nparams].lam3 < 0.0 || params[nparams].biga < 0.0 || + params[nparams].powerm - params[nparams].powermint != 0.0 || + (params[nparams].powermint != 3 && params[nparams].powermint != 1) || + params[nparams].gamma < 0.0 || + params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 || + params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0) + error->all(FLERR,"Illegal Tersoff parameter"); + + nparams++; + } + + delete [] words; +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffZBLOMP::force_zeta(Param *param, double rsq, double zeta_ij, + double &fforce, double &prefactor, + int eflag, double &eng) +{ + double r,fa,fa_d,bij; + + r = sqrt(rsq); + + fa = (r > param->bigr + param->bigd) ? 0.0 : + -param->bigb * exp(-param->lam2 * r) * ters_fc(r,param) * + F_fermi(r,param->ZBLexpscale,param->ZBLcut); + + fa_d = (r > param->bigr + param->bigd) ? 0.0 : + param->bigb * exp(-param->lam2 * r) * + (param->lam2 * ters_fc(r,param) * + F_fermi(r,param->ZBLexpscale,param->ZBLcut) - + ters_fc_d(r,param) * F_fermi(r,param->ZBLexpscale,param->ZBLcut) + - ters_fc(r,param) * F_fermi_d(r,param->ZBLexpscale,param->ZBLcut)); + + bij = ters_bij(zeta_ij,param); + fforce = 0.5*bij*fa_d / r; + prefactor = -0.5*fa * ters_bij_d(zeta_ij,param); + if (eflag) eng = 0.5*bij*fa; +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffZBLOMP::repulsive(Param *param, double rsq, double &fforce, + int eflag, double &eng) +{ + double r,tmp_fc,tmp_fc_d,tmp_exp; + + // Tersoff repulsive portion + + r = sqrt(rsq); + tmp_fc = ters_fc(r,param); + tmp_fc_d = ters_fc_d(r,param); + tmp_exp = exp(-param->lam1 * r); + double fforce_ters = param->biga * tmp_exp * (tmp_fc_d - tmp_fc*param->lam1); + double eng_ters = tmp_fc * param->biga * tmp_exp; + + // ZBL repulsive portion + + double esq = pow(global_e,2.0); + double a_ij = (0.8854*global_a_0) / + (pow(param->Z_i,0.23) + pow(param->Z_j,0.23)); + double premult = (param->Z_i * param->Z_j * esq)/(4.0*MY_PI*global_epsilon_0); + double r_ov_a = r/a_ij; + double phi = 0.1818*exp(-3.2*r_ov_a) + 0.5099*exp(-0.9423*r_ov_a) + + 0.2802*exp(-0.4029*r_ov_a) + 0.02817*exp(-0.2016*r_ov_a); + double dphi = (1.0/a_ij) * (-3.2*0.1818*exp(-3.2*r_ov_a) - + 0.9423*0.5099*exp(-0.9423*r_ov_a) - + 0.4029*0.2802*exp(-0.4029*r_ov_a) - + 0.2016*0.02817*exp(-0.2016*r_ov_a)); + double fforce_ZBL = premult*-pow(r,-2.0)* phi + premult*pow(r,-1.0)*dphi; + double eng_ZBL = premult*(1.0/r)*phi; + + // combine two parts with smoothing by Fermi-like function + + fforce = -(-F_fermi_d(r,param->ZBLexpscale,param->ZBLcut) * eng_ZBL + + (1.0 - F_fermi(r,param->ZBLexpscale,param->ZBLcut))*fforce_ZBL + + F_fermi_d(r,param->ZBLexpscale,param->ZBLcut)*eng_ters + + F_fermi(r,param->ZBLexpscale,param->ZBLcut)*fforce_ters) / r; + + if (eflag) + eng = (1.0 - F_fermi(r,param->ZBLexpscale,param->ZBLcut))*eng_ZBL + + F_fermi(r,param->ZBLexpscale,param->ZBLcut)*eng_ters; +} + diff --git a/src/USER-OMP/pair_tersoff_zbl_omp.h b/src/USER-OMP/pair_tersoff_zbl_omp.h new file mode 100644 index 0000000000..84d6ef1135 --- /dev/null +++ b/src/USER-OMP/pair_tersoff_zbl_omp.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tersoff/zbl/omp,PairTersoffZBLOMP) + +#else + +#ifndef LMP_PAIR_TERSOFF_ZBL_OMP_H +#define LMP_PAIR_TERSOFF_ZBL_OMP_H + +#include "pair_tersoff_omp.h" + +namespace LAMMPS_NS { + +class PairTersoffZBLOMP : public PairTersoffOMP { + public: + PairTersoffZBLOMP(class LAMMPS *); + virtual ~PairTersoffZBLOMP() {} + + protected: + double global_a_0; // Bohr radius for Coulomb repulsion + double global_epsilon_0; // permittivity of vacuum for Coulomb repulsion + double global_e; // proton charge (negative of electron charge) + + virtual void read_file(char *); + virtual void repulsive(Param *, double, double &, int, double &); + virtual void force_zeta(Param *, double, double, double &, double &, int, double &); + +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.cpp b/src/USER-OMP/pair_yukawa_colloid_omp.cpp new file mode 100644 index 0000000000..710ad9df18 --- /dev/null +++ b/src/USER-OMP/pair_yukawa_colloid_omp.cpp @@ -0,0 +1,164 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_yukawa_colloid_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairYukawaColloidOMP::PairYukawaColloidOMP(LAMMPS *lmp) : + PairYukawaColloid(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairYukawaColloidOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairYukawaColloidOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,radi,radj; + double rsq,r,rinv,r2inv,screening,forceyukawa,factor; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + r = sqrt(rsq); + rinv = 1.0/r; + screening = exp(-kappa*(r-(radi+radj))); + forceyukawa = a[itype][jtype] * screening; + + fpair = factor*forceyukawa * rinv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = a[itype][jtype]/kappa * screening - offset[itype][jtype]; + evdwl *= factor; + } + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairYukawaColloidOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairYukawaColloid::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.h b/src/USER-OMP/pair_yukawa_colloid_omp.h new file mode 100644 index 0000000000..9483cd15c1 --- /dev/null +++ b/src/USER-OMP/pair_yukawa_colloid_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(yukawa/colloid/omp,PairYukawaColloidOMP) + +#else + +#ifndef LMP_PAIR_YUKAWA_COLLOID_OMP_H +#define LMP_PAIR_YUKAWA_COLLOID_OMP_H + +#include "pair_yukawa_colloid.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairYukawaColloidOMP : public PairYukawaColloid, public ThrOMP { + + public: + PairYukawaColloidOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/pair_yukawa_omp.cpp b/src/USER-OMP/pair_yukawa_omp.cpp new file mode 100644 index 0000000000..1380e2239c --- /dev/null +++ b/src/USER-OMP/pair_yukawa_omp.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "pair_yukawa_omp.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairYukawaOMP::PairYukawaOMP(LAMMPS *lmp) : + PairYukawa(lmp), ThrOMP(lmp, PAIR) +{ + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +void PairYukawaOMP::compute(int eflag, int vflag) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + ev_setup_thr(this); + } else evflag = vflag_fdotr = 0; + + const int nall = atom->nlocal + atom->nghost; + const int nthreads = comm->nthreads; + const int inum = list->inum; + +#if defined(_OPENMP) +#pragma omp parallel default(shared) +#endif + { + int ifrom, ito, tid; + double **f; + + f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); + + if (evflag) { + if (eflag) { + if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid); + else eval<1,1,0>(f, ifrom, ito, tid); + } else { + if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid); + else eval<1,0,0>(f, ifrom, ito, tid); + } + } else { + if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid); + else eval<0,0,0>(f, ifrom, ito, tid); + } + + // reduce per thread forces into global force array. + data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); + } // end of omp parallel region + + // reduce per thread energy and virial, if requested. + if (evflag) ev_reduce_thr(this); + if (vflag_fdotr) virial_fdotr_compute(); +} + +template +void PairYukawaOMP::eval(double **f, int iifrom, int iito, int tid) +{ + int i,j,ii,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r,rinv,screening,forceyukawa,factor; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + double fxtmp,fytmp,fztmp; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = iifrom; ii < iito; ++ii) { + + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + fxtmp=fytmp=fztmp=0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + 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; + r = sqrt(rsq); + rinv = 1.0/r; + screening = exp(-kappa*r); + forceyukawa = a[itype][jtype] * screening * (kappa + rinv); + + fpair = factor*forceyukawa * r2inv; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (EFLAG) { + evdwl = a[itype][jtype] * screening * rinv - offset[itype][jtype]; + evdwl *= factor; + } + + if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR, + evdwl,0.0,fpair,delx,dely,delz,tid); + } + } + f[i][0] += fxtmp; + f[i][1] += fytmp; + f[i][2] += fztmp; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairYukawaOMP::memory_usage() +{ + double bytes = memory_usage_thr(); + bytes += PairYukawa::memory_usage(); + + return bytes; +} diff --git a/src/USER-OMP/pair_yukawa_omp.h b/src/USER-OMP/pair_yukawa_omp.h new file mode 100644 index 0000000000..e363ac6d17 --- /dev/null +++ b/src/USER-OMP/pair_yukawa_omp.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(yukawa/omp,PairYukawaOMP) + +#else + +#ifndef LMP_PAIR_YUKAWA_OMP_H +#define LMP_PAIR_YUKAWA_OMP_H + +#include "pair_yukawa.h" +#include "thr_omp.h" + +namespace LAMMPS_NS { + +class PairYukawaOMP : public PairYukawa, public ThrOMP { + + public: + PairYukawaOMP(class LAMMPS *); + + virtual void compute(int, int); + virtual double memory_usage(); + + private: + template + void eval(double **f, int ifrom, int ito, int tid); +}; + +} + +#endif +#endif diff --git a/src/USER-OMP/thr_omp.cpp b/src/USER-OMP/thr_omp.cpp index d05fae5b33..37ce1f198b 100644 --- a/src/USER-OMP/thr_omp.cpp +++ b/src/USER-OMP/thr_omp.cpp @@ -31,7 +31,10 @@ #include #endif +#include "math_const.h" + using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -40,6 +43,7 @@ ThrOMP::ThrOMP(LAMMPS *ptr, int style) : thr_style(style), lmp(ptr) // initialize fixed size per thread storage eng_vdwl_thr = eng_coul_thr = eng_bond_thr = NULL; virial_thr = NULL; + lmp->memory->create(eng_vdwl_thr,lmp->comm->nthreads,"thr_omp:eng_vdwl_thr"); lmp->memory->create(eng_coul_thr,lmp->comm->nthreads,"thr_omp:eng_coul_thr"); lmp->memory->create(eng_bond_thr,lmp->comm->nthreads,"thr_omp:eng_bond_thr"); @@ -48,6 +52,7 @@ ThrOMP::ThrOMP(LAMMPS *ptr, int style) : thr_style(style), lmp(ptr) // variable size per thread, per atom storage // the actually allocation happens via memory->grow() in ev_steup_thr() maxeatom_thr = maxvatom_thr = 0; + evflag_global = evflag_atom = 0; eatom_thr = NULL; vatom_thr = NULL; } @@ -66,10 +71,13 @@ ThrOMP::~ThrOMP() /* ---------------------------------------------------------------------- */ -void ThrOMP::ev_zero_acc_thr(int ntotal, int eflag_global, int vflag_global, +void ThrOMP::ev_setup_acc_thr(int ntotal, int eflag_global, int vflag_global, int eflag_atom, int vflag_atom, int nthreads) { int t,i; + + evflag_global = (eflag_global || vflag_global); + evflag_atom = (eflag_atom || vflag_atom); for (t = 0; t < nthreads; ++t) { @@ -115,9 +123,9 @@ void ThrOMP::ev_setup_thr(Dihedral *dihed) int ntotal = (lmp->force->newton_bond) ? (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal; - // zero per thread accumulators - ev_zero_acc_thr(ntotal, dihed->eflag_global, dihed->vflag_global, - dihed->eflag_atom, dihed->vflag_atom, nthreads); + // set up per thread accumulators + ev_setup_acc_thr(ntotal, dihed->eflag_global, dihed->vflag_global, + dihed->eflag_atom, dihed->vflag_atom, nthreads); } /* ---------------------------------------------------------------------- */ @@ -139,9 +147,9 @@ void ThrOMP::ev_setup_thr(Pair *pair) int ntotal = (lmp->force->newton) ? (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal; - // zero per thread accumulators - ev_zero_acc_thr(ntotal, pair->eflag_global, pair->vflag_global, - pair->eflag_atom, pair->vflag_atom, nthreads); + // set up per thread accumulators + ev_setup_acc_thr(ntotal, pair->eflag_global, pair->vflag_global, + pair->eflag_atom, pair->vflag_atom, nthreads); } /* ---------------------------------------------------------------------- @@ -181,6 +189,44 @@ void ThrOMP::ev_reduce_thr(Dihedral *dihed) } } +/* ---------------------------------------------------------------------- + reduce the per thread accumulated E/V data into the canonical accumulators. +------------------------------------------------------------------------- */ +void ThrOMP::ev_reduce_thr(Pair *pair) +{ + const int nthreads = lmp->comm->nthreads; + const int ntotal = (lmp->force->newton) ? + (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal; + + for (int n = 0; n < nthreads; ++n) { + pair->eng_vdwl += eng_vdwl_thr[n]; + pair->eng_coul += eng_coul_thr[n]; + if (pair->vflag_either) { + pair->virial[0] += virial_thr[n][0]; + pair->virial[1] += virial_thr[n][1]; + pair->virial[2] += virial_thr[n][2]; + pair->virial[3] += virial_thr[n][3]; + pair->virial[4] += virial_thr[n][4]; + pair->virial[5] += virial_thr[n][5]; + if (pair->vflag_atom) { + for (int i = 0; i < ntotal; ++i) { + pair->vatom[i][0] += vatom_thr[n][i][0]; + pair->vatom[i][1] += vatom_thr[n][i][1]; + pair->vatom[i][2] += vatom_thr[n][i][2]; + pair->vatom[i][3] += vatom_thr[n][i][3]; + pair->vatom[i][4] += vatom_thr[n][i][4]; + pair->vatom[i][5] += vatom_thr[n][i][5]; + } + } + } + if (pair->eflag_atom) { + for (int i = 0; i < ntotal; ++i) { + pair->eatom[i] += eatom_thr[n][i]; + } + } + } +} + /* ---------------------------------------------------------------------- tally eng_vdwl and virial into per thread global and per-atom accumulators need i < nlocal test since called by bond_quartic and dihedral_charmm @@ -276,43 +322,444 @@ void ThrOMP::ev_tally_thr(Pair *pair, int i, int j, int nlocal, } /* ---------------------------------------------------------------------- - reduce the per thread accumulated E/V data into the canonical accumulators. + tally eng_vdwl and virial into global and per-atom accumulators + for virial, have delx,dely,delz and fx,fy,fz ------------------------------------------------------------------------- */ -void ThrOMP::ev_reduce_thr(Pair *pair) -{ - const int nthreads = lmp->comm->nthreads; - const int ntotal = (lmp->force->newton) ? - (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal; - for (int n = 0; n < nthreads; ++n) { - pair->eng_vdwl += eng_vdwl_thr[n]; - pair->eng_coul += eng_coul_thr[n]; - if (pair->vflag_either) { - pair->virial[0] += virial_thr[n][0]; - pair->virial[1] += virial_thr[n][1]; - pair->virial[2] += virial_thr[n][2]; - pair->virial[3] += virial_thr[n][3]; - pair->virial[4] += virial_thr[n][4]; - pair->virial[5] += virial_thr[n][5]; - if (pair->vflag_atom) { - for (int i = 0; i < ntotal; ++i) { - pair->vatom[i][0] += vatom_thr[n][i][0]; - pair->vatom[i][1] += vatom_thr[n][i][1]; - pair->vatom[i][2] += vatom_thr[n][i][2]; - pair->vatom[i][3] += vatom_thr[n][i][3]; - pair->vatom[i][4] += vatom_thr[n][i][4]; - pair->vatom[i][5] += vatom_thr[n][i][5]; - } +void ThrOMP::ev_tally_xyz_thr(Pair *pair, int i, int j, int nlocal, + int newton_pair, double evdwl, double ecoul, + double fx, double fy, double fz, + double delx, double dely, double delz, int tid) +{ + double evdwlhalf,ecoulhalf,epairhalf,v[6]; + + if (pair->eflag_either) { + if (pair->eflag_global) { + if (newton_pair) { + eng_vdwl_thr[tid] += evdwl; + eng_coul_thr[tid] += ecoul; + } else { + evdwlhalf = 0.5*evdwl; + ecoulhalf = 0.5*ecoul; + if (i < nlocal) { + eng_vdwl_thr[tid] += evdwlhalf; + eng_coul_thr[tid] += ecoulhalf; + } + if (j < nlocal) { + eng_vdwl_thr[tid] += evdwlhalf; + eng_coul_thr[tid] += ecoulhalf; + } } } if (pair->eflag_atom) { - for (int i = 0; i < ntotal; ++i) { - pair->eatom[i] += eatom_thr[n][i]; + epairhalf = 0.5 * (evdwl + ecoul); + if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf; + if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf; + } + } + + if (pair->vflag_either) { + v[0] = delx*fx; + v[1] = dely*fy; + v[2] = delz*fz; + v[3] = delx*fy; + v[4] = delx*fz; + v[5] = dely*fz; + + if (pair->vflag_global) { + if (newton_pair) { + virial_thr[tid][0] += v[0]; + virial_thr[tid][1] += v[1]; + virial_thr[tid][2] += v[2]; + virial_thr[tid][3] += v[3]; + virial_thr[tid][4] += v[4]; + virial_thr[tid][5] += v[5]; + } else { + if (i < nlocal) { + virial_thr[tid][0] += 0.5*v[0]; + virial_thr[tid][1] += 0.5*v[1]; + virial_thr[tid][2] += 0.5*v[2]; + virial_thr[tid][3] += 0.5*v[3]; + virial_thr[tid][4] += 0.5*v[4]; + virial_thr[tid][5] += 0.5*v[5]; + } + if (j < nlocal) { + virial_thr[tid][0] += 0.5*v[0]; + virial_thr[tid][1] += 0.5*v[1]; + virial_thr[tid][2] += 0.5*v[2]; + virial_thr[tid][3] += 0.5*v[3]; + virial_thr[tid][4] += 0.5*v[4]; + virial_thr[tid][5] += 0.5*v[5]; + } + } + } + + if (pair->vflag_atom) { + if (newton_pair || i < nlocal) { + vatom_thr[tid][i][0] += 0.5*v[0]; + vatom_thr[tid][i][1] += 0.5*v[1]; + vatom_thr[tid][i][2] += 0.5*v[2]; + vatom_thr[tid][i][3] += 0.5*v[3]; + vatom_thr[tid][i][4] += 0.5*v[4]; + vatom_thr[tid][i][5] += 0.5*v[5]; + } + if (newton_pair || j < nlocal) { + vatom_thr[tid][j][0] += 0.5*v[0]; + vatom_thr[tid][j][1] += 0.5*v[1]; + vatom_thr[tid][j][2] += 0.5*v[2]; + vatom_thr[tid][j][3] += 0.5*v[3]; + vatom_thr[tid][j][4] += 0.5*v[4]; + vatom_thr[tid][j][5] += 0.5*v[5]; } } } } +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by SW and hbond potentials, newton_pair is always on + virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk + ------------------------------------------------------------------------- */ + +void ThrOMP::ev_tally3_thr(Pair *pair, int i, int j, int k, double evdwl, double ecoul, + double *fj, double *fk, double *drji, double *drki, int tid) +{ + double epairthird,v[6]; + + if (pair->eflag_either) { + if (pair->eflag_global) { + eng_vdwl_thr[tid] += evdwl; + eng_coul_thr[tid] += ecoul; + } + if (pair->eflag_atom) { + epairthird = THIRD * (evdwl + ecoul); + eatom_thr[tid][i] += epairthird; + eatom_thr[tid][j] += epairthird; + eatom_thr[tid][k] += epairthird; + } + } + + if (pair->vflag_either) { + v[0] = drji[0]*fj[0] + drki[0]*fk[0]; + v[1] = drji[1]*fj[1] + drki[1]*fk[1]; + v[2] = drji[2]*fj[2] + drki[2]*fk[2]; + v[3] = drji[0]*fj[1] + drki[0]*fk[1]; + v[4] = drji[0]*fj[2] + drki[0]*fk[2]; + v[5] = drji[1]*fj[2] + drki[1]*fk[2]; + + if (pair->vflag_global) { + virial_thr[tid][0] += v[0]; + virial_thr[tid][1] += v[1]; + virial_thr[tid][2] += v[2]; + virial_thr[tid][3] += v[3]; + virial_thr[tid][4] += v[4]; + virial_thr[tid][5] += v[5]; + } + + if (pair->vflag_atom) { + for (int n=0; n < 6; ++n) { + vatom_thr[tid][i][n] += THIRD*v[n]; + vatom_thr[tid][j][n] += THIRD*v[n]; + vatom_thr[tid][k][n] += THIRD*v[n]; + } + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by AIREBO potential, newton_pair is always on + ------------------------------------------------------------------------- */ + +void ThrOMP::ev_tally4_thr(Pair *pair, int i, int j, int k, int m, double evdwl, + double *fi, double *fj, double *fk, + double *drim, double *drjm, double *drkm,int tid) +{ + double epairfourth,v[6]; + + if (pair->eflag_either) { + if (pair->eflag_global) eng_vdwl_thr[tid] += evdwl; + if (pair->eflag_atom) { + epairfourth = 0.25 * evdwl; + eatom_thr[tid][i] += epairfourth; + eatom_thr[tid][j] += epairfourth; + eatom_thr[tid][k] += epairfourth; + eatom_thr[tid][m] += epairfourth; + } + } + + if (pair->vflag_atom) { + v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]); + v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]); + v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]); + v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]); + v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]); + v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]); + + vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2]; + vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5]; + vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2]; + vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5]; + vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2]; + vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5]; + vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2]; + vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5]; + } +} + +/* ---------------------------------------------------------------------- + tally ecoul and virial into each of n atoms in list + called by TIP4P potential, newton_pair is always on + changes v values by dividing by n + ------------------------------------------------------------------------- */ + +void ThrOMP::ev_tally_list_thr(Pair *pair, int n, int *list, double ecoul, double *v, int tid) +{ + int i,j; + + if (pair->eflag_either) { + if (pair->eflag_global) eng_coul_thr[tid] += ecoul; + if (pair->eflag_atom) { + double epairatom = ecoul/n; + for (i = 0; i < n; i++) eatom_thr[tid][list[i]] += epairatom; + } + } + + if (pair->vflag_either) { + if (pair->vflag_global) { + virial_thr[tid][0] += v[0]; + virial_thr[tid][1] += v[1]; + virial_thr[tid][2] += v[2]; + virial_thr[tid][3] += v[3]; + virial_thr[tid][4] += v[4]; + virial_thr[tid][5] += v[5]; + } + + if (pair->vflag_atom) { + v[0] /= n; + v[1] /= n; + v[2] /= n; + v[3] /= n; + v[4] /= n; + v[5] /= n; + for (i = 0; i < n; i++) { + j = list[i]; + vatom_thr[tid][j][0] += v[0]; + vatom_thr[tid][j][1] += v[1]; + vatom_thr[tid][j][2] += v[2]; + vatom_thr[tid][j][3] += v[3]; + vatom_thr[tid][j][4] += v[4]; + vatom_thr[tid][j][5] += v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators + virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4 + = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4 + = vb1*f1 + vb2*f3 + (vb3+vb2)*f4 +------------------------------------------------------------------------- */ + +void ThrOMP::ev_tally_thr(Dihedral *dihed, int i1, int i2, int i3, int i4, + int nlocal, int newton_bond, + double edihedral, double *f1, double *f3, double *f4, + double vb1x, double vb1y, double vb1z, + double vb2x, double vb2y, double vb2z, + double vb3x, double vb3y, double vb3z, int tid) +{ + double edihedralquarter,v[6]; + int cnt; + + if (dihed->eflag_either) { + if (dihed->eflag_global) { + if (newton_bond) { + eng_bond_thr[tid] += edihedral; + } else { + edihedralquarter = 0.25*edihedral; + cnt = 0; + if (i1 < nlocal) ++cnt; + if (i2 < nlocal) ++cnt; + if (i3 < nlocal) ++cnt; + if (i4 < nlocal) ++cnt; + eng_bond_thr[tid] += static_cast(cnt) * edihedralquarter; + } + } + if (dihed->eflag_atom) { + edihedralquarter = 0.25*edihedral; + if (newton_bond || i1 < nlocal) eatom_thr[tid][i1] += edihedralquarter; + if (newton_bond || i2 < nlocal) eatom_thr[tid][i2] += edihedralquarter; + if (newton_bond || i3 < nlocal) eatom_thr[tid][i3] += edihedralquarter; + if (newton_bond || i4 < nlocal) eatom_thr[tid][i4] += edihedralquarter; + } + } + + if (dihed->vflag_either) { + v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0]; + v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1]; + v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2]; + v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1]; + v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2]; + v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2]; + + if (dihed->vflag_global) { + if (newton_bond) { + virial_thr[tid][0] += v[0]; + virial_thr[tid][1] += v[1]; + virial_thr[tid][2] += v[2]; + virial_thr[tid][3] += v[3]; + virial_thr[tid][4] += v[4]; + virial_thr[tid][5] += v[5]; + } else { + if (i1 < nlocal) { + virial_thr[tid][0] += 0.25*v[0]; + virial_thr[tid][1] += 0.25*v[1]; + virial_thr[tid][2] += 0.25*v[2]; + virial_thr[tid][3] += 0.25*v[3]; + virial_thr[tid][4] += 0.25*v[4]; + virial_thr[tid][5] += 0.25*v[5]; + } + if (i2 < nlocal) { + virial_thr[tid][0] += 0.25*v[0]; + virial_thr[tid][1] += 0.25*v[1]; + virial_thr[tid][2] += 0.25*v[2]; + virial_thr[tid][3] += 0.25*v[3]; + virial_thr[tid][4] += 0.25*v[4]; + virial_thr[tid][5] += 0.25*v[5]; + } + if (i3 < nlocal) { + virial_thr[tid][0] += 0.25*v[0]; + virial_thr[tid][1] += 0.25*v[1]; + virial_thr[tid][2] += 0.25*v[2]; + virial_thr[tid][3] += 0.25*v[3]; + virial_thr[tid][4] += 0.25*v[4]; + virial_thr[tid][5] += 0.25*v[5]; + } + if (i4 < nlocal) { + virial_thr[tid][0] += 0.25*v[0]; + virial_thr[tid][1] += 0.25*v[1]; + virial_thr[tid][2] += 0.25*v[2]; + virial_thr[tid][3] += 0.25*v[3]; + virial_thr[tid][4] += 0.25*v[4]; + virial_thr[tid][5] += 0.25*v[5]; + } + } + } + + if (dihed->vflag_atom) { + if (newton_bond || i1 < nlocal) { + vatom_thr[tid][i1][0] += 0.25*v[0]; + vatom_thr[tid][i1][1] += 0.25*v[1]; + vatom_thr[tid][i1][2] += 0.25*v[2]; + vatom_thr[tid][i1][3] += 0.25*v[3]; + vatom_thr[tid][i1][4] += 0.25*v[4]; + vatom_thr[tid][i1][5] += 0.25*v[5]; + } + if (newton_bond || i2 < nlocal) { + vatom_thr[tid][i2][0] += 0.25*v[0]; + vatom_thr[tid][i2][1] += 0.25*v[1]; + vatom_thr[tid][i2][2] += 0.25*v[2]; + vatom_thr[tid][i2][3] += 0.25*v[3]; + vatom_thr[tid][i2][4] += 0.25*v[4]; + vatom_thr[tid][i2][5] += 0.25*v[5]; + } + if (newton_bond || i3 < nlocal) { + vatom_thr[tid][i3][0] += 0.25*v[0]; + vatom_thr[tid][i3][1] += 0.25*v[1]; + vatom_thr[tid][i3][2] += 0.25*v[2]; + vatom_thr[tid][i3][3] += 0.25*v[3]; + vatom_thr[tid][i3][4] += 0.25*v[4]; + vatom_thr[tid][i3][5] += 0.25*v[5]; + } + if (newton_bond || i4 < nlocal) { + vatom_thr[tid][i4][0] += 0.25*v[0]; + vatom_thr[tid][i4][1] += 0.25*v[1]; + vatom_thr[tid][i4][2] += 0.25*v[2]; + vatom_thr[tid][i4][3] += 0.25*v[3]; + vatom_thr[tid][i4][4] += 0.25*v[4]; + vatom_thr[tid][i4][5] += 0.25*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- + tally virial into per-atom accumulators + called by AIREBO potential, newton_pair is always on + fpair is magnitude of force on atom I +------------------------------------------------------------------------- */ + +void ThrOMP::v_tally2_thr(int i, int j, double fpair, double *drij, int tid) +{ + double v[6]; + + v[0] = 0.5 * drij[0]*drij[0]*fpair; + v[1] = 0.5 * drij[1]*drij[1]*fpair; + v[2] = 0.5 * drij[2]*drij[2]*fpair; + v[3] = 0.5 * drij[0]*drij[1]*fpair; + v[4] = 0.5 * drij[0]*drij[2]*fpair; + v[5] = 0.5 * drij[1]*drij[2]*fpair; + + vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2]; + vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5]; + vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2]; + vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5]; +} + +/* ---------------------------------------------------------------------- + tally virial into per-atom accumulators + called by AIREBO and Tersoff potential, newton_pair is always on +------------------------------------------------------------------------- */ + +void ThrOMP::v_tally3_thr(int i, int j, int k, double *fi, double *fj, + double *drik, double *drjk, int tid) +{ + double v[6]; + + v[0] = THIRD * (drik[0]*fi[0] + drjk[0]*fj[0]); + v[1] = THIRD * (drik[1]*fi[1] + drjk[1]*fj[1]); + v[2] = THIRD * (drik[2]*fi[2] + drjk[2]*fj[2]); + v[3] = THIRD * (drik[0]*fi[1] + drjk[0]*fj[1]); + v[4] = THIRD * (drik[0]*fi[2] + drjk[0]*fj[2]); + v[5] = THIRD * (drik[1]*fi[2] + drjk[1]*fj[2]); + + vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2]; + vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5]; + vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2]; + vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5]; + vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2]; + vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5]; +} + +/* ---------------------------------------------------------------------- + tally virial into per-atom accumulators + called by AIREBO potential, newton_pair is always on +------------------------------------------------------------------------- */ + +void ThrOMP::v_tally4_thr(int i, int j, int k, int m, + double *fi, double *fj, double *fk, + double *drim, double *drjm, double *drkm, int tid) +{ + double v[6]; + + v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]); + v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]); + v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]); + v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]); + v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]); + v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]); + + vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2]; + vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5]; + vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2]; + vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5]; + vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2]; + vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5]; + vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2]; + vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5]; +} + /* ---------------------------------------------------------------------- */ // set loop range thread id, and force array offset for threaded runs. @@ -320,56 +767,50 @@ double **ThrOMP::loop_setup_thr(double **f, int &ifrom, int &ito, int &tid, int inum, int nall, int nthreads) { #if defined(_OPENMP) - if (nthreads > 1) { - tid = omp_get_thread_num(); + tid = omp_get_thread_num(); - // each thread works on a fixed chunk of atoms. - const int idelta = 1 + inum/nthreads; - ifrom = tid*idelta; - ito = ifrom + idelta; - if (ito > inum) - ito = inum; - - return f + nall*tid; - - } else { -#endif - tid = 0; - ifrom = 0; + // each thread works on a fixed chunk of atoms. + const int idelta = 1 + inum/nthreads; + ifrom = tid*idelta; + ito = ifrom + idelta; + if (ito > inum) ito = inum; - return f; -#if defined(_OPENMP) - } + + return f + nall*tid; +#else + tid = 0; + ifrom = 0; + ito = inum; + return f; #endif } /* ---------------------------------------------------------------------- */ -// reduce per thread forces into the first part of the force +// reduce per thread data into the first part of the data // array that is used for the non-threaded parts and reset -// the temporary storage to 0.0. this routine depends on the -// forces arrays stored in this order x1,y1,z1,x2,y2,z2,... +// the temporary storage to 0.0. this routine depends on +// multi-dimensional arrays like force stored in this order +// x1,y1,z1,x2,y2,z2,... // we need to post a barrier to wait until all threads are done -// with computing forces. -void ThrOMP::force_reduce_thr(double *fall, int nall, - int nthreads, int tid) +// with writing to the array . +void ThrOMP::data_reduce_thr(double *dall, int nall, int nthreads, + int ndim, int tid) { #if defined(_OPENMP) // NOOP in non-threaded execution. if (nthreads == 1) return; #pragma omp barrier { - double *f; - const int idelta = 1 + nall/nthreads; - const int ifrom = 3*tid*idelta; - const int ito = 3*(((ifrom + idelta) > nall) ? nall : (ifrom + idelta)); + const int nvals = ndim*nall; + const int idelta = nvals/nthreads + 1; + const int ifrom = tid*idelta; + const int ito = ((ifrom + idelta) > nvals) ? nvals : (ifrom + idelta); - for (int n = 1; n < nthreads; ++n) { - const int toffs = 3*n*nall; - f = fall + toffs; - for (int m = ifrom; m < ito; ++m) { - fall[m] += f[m]; - f[m] = 0.0; + for (int m = ifrom; m < ito; ++m) { + for (int n = 1; n < nthreads; ++n) { + dall[m] += dall[n*nvals + m]; + dall[n*nvals + m] = 0.0; } } } diff --git a/src/USER-OMP/thr_omp.h b/src/USER-OMP/thr_omp.h index 24963e91d4..9966c9de00 100644 --- a/src/USER-OMP/thr_omp.h +++ b/src/USER-OMP/thr_omp.h @@ -27,6 +27,13 @@ class Pair; class Dihedral; class ThrOMP { + public: + struct global { + double eng_vdwl; + double eng_coul; + double eng_bond; + double virial[6]; + }; protected: const int thr_style; @@ -43,6 +50,7 @@ class ThrOMP { double ***vatom_thr; // per thread per atom virial int maxeatom_thr, maxvatom_thr; + int evflag_global, evflag_atom; public: ThrOMP(LAMMPS *, int); @@ -50,6 +58,13 @@ class ThrOMP { double memory_usage_thr(); + inline void sync_threads() { +#if defined(_OPENMP) +#pragma omp barrier +#endif + { ; } + }; + protected: // extra ev_tally work for threaded styles void ev_setup_thr(Pair *); @@ -60,19 +75,39 @@ class ThrOMP { private: // internal method to be used by multiple ev_setup_thr() methods - void ev_zero_acc_thr(int, int, int, int, int, int); + void ev_setup_acc_thr(int, int, int, int, int, int); protected: // threading adapted versions of the ev_tally infrastructure + // style specific versions (need access to style class flags) void ev_tally_thr(Pair *, int, int, int, int, double, double, double, double, double, double, int); + void ev_tally_xyz_thr(Pair *, int, int, int, int, double, double, + double, double, double, double, double, double, int); + void ev_tally3_thr(Pair *, int, int, int, double, double, + double *, double *, double *, double *, int); + void ev_tally4_thr(Pair *, int, int, int, int, double, + double *, double *, double *, + double *, double *, double *, int); + void ev_tally_list_thr(Pair *, int, int *, double , double *, int); + + void ev_tally_thr(Dihedral *, int, int, int, int, int, int, double, + double *, double *, double *, double, double, double, + double, double, double, double, double, double, int); + + // style independent versions + void v_tally2_thr(int, int, double, double *, int); + void v_tally3_thr(int, int, int, double *, double *, double *, double *, int); + void v_tally4_thr(int, int, int, int, double *, double *, double *, + double *, double *, double *, int); protected: // set loop range, thread id, and force array offset for threaded runs. double **loop_setup_thr(double **, int &, int &, int &, int, int, int); - // reduce per thread forces into the first part of the force array - void force_reduce_thr(double *, int, int, int); + // reduce per thread data into the first part of the array + void data_reduce_thr(double *, int, int, int, int); + }; } From 855e2aa3538e57f1b1adf548b3f742c614efad0c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:13:19 +0000 Subject: [PATCH 192/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7067 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-OMP/fix_qeq_comb_omp.cpp | 166 --------- src/USER-OMP/fix_qeq_comb_omp.h | 32 -- src/USER-OMP/pair_comb_omp.cpp | 540 ------------------------------ src/USER-OMP/pair_comb_omp.h | 45 --- 4 files changed, 783 deletions(-) delete mode 100644 src/USER-OMP/fix_qeq_comb_omp.cpp delete mode 100644 src/USER-OMP/fix_qeq_comb_omp.h delete mode 100644 src/USER-OMP/pair_comb_omp.cpp delete mode 100644 src/USER-OMP/pair_comb_omp.h diff --git a/src/USER-OMP/fix_qeq_comb_omp.cpp b/src/USER-OMP/fix_qeq_comb_omp.cpp deleted file mode 100644 index 175bab8986..0000000000 --- a/src/USER-OMP/fix_qeq_comb_omp.cpp +++ /dev/null @@ -1,166 +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. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Axel Kohlmeyer (Temple U) -------------------------------------------------------------------------- */ - -#include "lmptype.h" -#include "mpi.h" -#include -#include "fix_qeq_comb_omp.h" -#include "atom.h" -#include "force.h" -#include "group.h" -#include "memory.h" -#include "error.h" -#include "respa.h" -#include "update.h" -#include "pair_comb_omp.h" - -#include - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -FixQEQCombOMP::FixQEQCombOMP(LAMMPS *lmp, int narg, char **arg) - : FixQEQComb(lmp, narg, arg) -{ - if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb/omp command"); -} - -/* ---------------------------------------------------------------------- */ - -void FixQEQCombOMP::init() -{ - if (!atom->q_flag) - error->all(FLERR,"Fix qeq/comb/omp requires atom attribute q"); - - comb = (PairComb *) force->pair_match("comb/omp",1); - if (comb == NULL) - comb = (PairComb *) force->pair_match("comb",1); - if (comb == NULL) error->all(FLERR,"Must use pair_style comb or comb/omp with fix qeq/comb"); - - if (strstr(update->integrate_style,"respa")) - nlevels_respa = ((Respa *) update->integrate)->nlevels; - - ngroup = group->count(igroup); - if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms"); -} - -/* ---------------------------------------------------------------------- */ - -void FixQEQCombOMP::post_force(int vflag) -{ - int i,iloop,loopmax; - double heatpq,qmass,dtq,dtq2; - double enegchkall,enegmaxall; - - if (update->ntimestep % nevery) return; - - // reallocate work arrays if necessary - // qf = charge force - // q1 = charge displacement - // q2 = tmp storage of charge force for next iteration - - if (atom->nmax > nmax) { - memory->destroy(qf); - memory->destroy(q1); - memory->destroy(q2); - nmax = atom->nmax; - memory->create(qf,nmax,"qeq:qf"); - memory->create(q1,nmax,"qeq:q1"); - memory->create(q2,nmax,"qeq:q2"); - vector_atom = qf; - } - - // more loops for first-time charge equilibrium - - iloop = 0; - if (firstflag) loopmax = 5000; - else loopmax = 2000; - - // charge-equilibration loop - - if (me == 0 && fp) - fprintf(fp,"Charge equilibration on step " BIGINT_FORMAT "\n", - update->ntimestep); - - heatpq = 0.05; - qmass = 0.000548580; - dtq = 0.0006; - dtq2 = 0.5*dtq*dtq/qmass; - - double enegchk = 0.0; - double enegtot = 0.0; - double enegmax = 0.0; - - double *q = atom->q; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - for (i = 0; i < nlocal; i++) - q1[i] = q2[i] = qf[i] = 0.0; - - for (iloop = 0; iloop < loopmax; iloop ++ ) { - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - q1[i] += qf[i]*dtq2 - heatpq*q1[i]; - q[i] += q1[i]; - } - - enegtot = comb->yasu_char(qf,igroup); - enegtot /= ngroup; - enegchk = enegmax = 0.0; - -#if defined(_OPENMP) -#pragma omp parallel for private(i) default(shared) -#endif - for (i = 0; i < nlocal ; i++) - if (mask[i] & groupbit) { - q2[i] = enegtot-qf[i]; - enegmax = MAX(enegmax,fabs(q2[i])); - enegchk += fabs(q2[i]); - qf[i] = q2[i]; - } - - MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world); - enegchk = enegchkall/ngroup; - MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world); - enegmax = enegmaxall; - - if (enegchk <= precision && enegmax <= 100.0*precision) break; - - if (me == 0 && fp) - fprintf(fp," iteration: %d, enegtot %.6g, " - "enegmax %.6g, fq deviation: %.6g\n", - iloop,enegtot,enegmax,enegchk); - -#if defined(_OPENMP) -#pragma omp parallel for private(i) default(shared) -#endif - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - q1[i] += qf[i]*dtq2 - heatpq*q1[i]; - } - - if (me == 0 && fp) { - if (iloop == loopmax) - fprintf(fp,"Charges did not converge in %d iterations\n",iloop); - else - fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n", - iloop,enegchk); - } -} - diff --git a/src/USER-OMP/fix_qeq_comb_omp.h b/src/USER-OMP/fix_qeq_comb_omp.h deleted file mode 100644 index 0febe6b0aa..0000000000 --- a/src/USER-OMP/fix_qeq_comb_omp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(qeq/comb/omp,FixQEQCombOMP) - -#else - -#ifndef LMP_FIX_QEQ_COMB_OMP_H -#define LMP_FIX_QEQ_COMB_OMP_H - -#include "fix_qeq_comb.h" - -namespace LAMMPS_NS { - -class FixQEQCombOMP : public FixQEQComb { - public: - FixQEQCombOMP(class LAMMPS *, int, char **); - virtual void init(); - virtual void post_force(int); -}; - -} - -#endif -#endif diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp deleted file mode 100644 index 207c122e45..0000000000 --- a/src/USER-OMP/pair_comb_omp.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - This software is distributed under the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Axel Kohlmeyer (Temple U) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "pair_comb_omp.h" -#include "atom.h" -#include "comm.h" -#include "group.h" -#include "force.h" -#include "memory.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -PairCombOMP::PairCombOMP(LAMMPS *lmp) : - PairComb(lmp), ThrOMP(lmp, PAIR) -{ - respa_enable = 0; -} - -/* ---------------------------------------------------------------------- */ - -void PairCombOMP::compute(int eflag, int vflag) -{ - if (eflag || vflag) { - ev_setup(eflag,vflag); - ev_setup_thr(this); - } else evflag = vflag_fdotr = vflag_atom = 0; - - const int nall = atom->nlocal + atom->nghost; - const int nthreads = comm->nthreads; - const int inum = list->inum; - - // grow coordination array if necessary - - if (atom->nmax > nmax) { - memory->destroy(NCo); - nmax = atom->nmax; - memory->create(NCo,nmax,"pair:NCo"); - } - -#if defined(_OPENMP) -#pragma omp parallel default(shared) -#endif - { - int ifrom, ito, tid; - double **f; - - f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads); - - if (evflag) { - if (eflag) { - if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid); - else eval<1,1,0>(f, ifrom, ito, tid); - } else { - if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid); - else eval<1,0,0>(f, ifrom, ito, tid); - } - } else eval<0,0,0>(f, ifrom, ito, tid); - - // reduce per thread forces into global force array. - data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid); - } // end of omp parallel region - - // reduce per thread energy and virial, if requested. - if (evflag) ev_reduce_thr(this); - if (vflag_fdotr) virial_fdotr_compute(); -} - -template -void PairCombOMP::eval(double **f, int iifrom, int iito, int tid) -{ - int i,j,k,ii,jj,kk,jnum,iparam_i; - int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; - double rsq,rsq1,rsq2; - double delr1[3],delr2[3],fi[3],fj[3],fk[3]; - double zeta_ij,prefactor; - int *ilist,*jlist,*numneigh,**firstneigh; - int mr1,mr2,mr3; - int rsc,inty; - double elp_ij,filp[3],fjlp[3],fklp[3]; - double iq,jq; - double yaself; - double potal,fac11,fac11e; - double vionij,fvionij,sr1,sr2,sr3,Eov,Fov; - - evdwl = ecoul = 0.0; - - double **x = atom->x; - double *q = atom->q; - int *tag = atom->tag; - int *type = atom->type; - int nlocal = atom->nlocal; - - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - yaself = vionij = fvionij = Eov = Fov = 0.0; - - double fxtmp,fytmp,fztmp; - double fjxtmp,fjytmp,fjztmp; - - // self energy correction term: potal - - potal_calc(potal,fac11,fac11e); - - // loop over full neighbor list of my atoms - - for (ii = iifrom; ii < iito; ++ii) { - - i = ilist[ii]; - itag = tag[i]; - itype = map[type[i]]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - fxtmp = fytmp = fztmp = 0.0; - - iq = q[i]; - NCo[i] = 0; - iparam_i = elem2param[itype][itype][itype]; - - // self energy, only on i atom - - yaself = self(¶ms[iparam_i],iq,potal); - - if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,yaself, - 0.0,0.0,0.0,0.0,0.0,tid); - - // two-body interactions (long and short repulsive) - - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - 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; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - - // Qj calculates 2-body Coulombic - - jtype = map[type[j]]; - jq = q[j]; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - iparam_ij = elem2param[itype][jtype][jtype]; - - // long range q-dependent - - if (rsq > params[iparam_ij].lcutsq) continue; - - inty = intype[itype][jtype]; - - // polynomial three-point interpolation - - tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype); - - // 1/r energy and forces - - direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq, - potal,fac11,fac11e,vionij,fvionij); - - // field correction to self energy - - field(¶ms[iparam_ij],rsq,iq,jq,vionij,fvionij); - - // polarization field - // sums up long range forces - - fxtmp += delx*fvionij; - fytmp += dely*fvionij; - fztmp += delz*fvionij; - f[j][0] -= delx*fvionij; - f[j][1] -= dely*fvionij; - f[j][2] -= delz*fvionij; - - if (EVFLAG) - ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, - 0.0,vionij,fvionij,delx,dely,delz,tid); - - // short range q-independent - - if (rsq > params[iparam_ij].cutsq) continue; - - repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl,iq,jq); - - // repulsion is pure two-body, sums up pair repulsive forces - - fxtmp += delx*fpair; - fytmp += dely*fpair; - fztmp += delz*fpair; - f[j][0] -= delx*fpair; - f[j][1] -= dely*fpair; - f[j][2] -= delz*fpair; - - if (EVFLAG) - ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, - evdwl,0.0,fpair,delx,dely,delz,tid); - } - - // accumulate coordination number information - - if (cor_flag) { - int numcoor = 0; - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - jtype = map[type[j]]; - iparam_ij = elem2param[itype][jtype][jtype]; - - if(params[iparam_ij].hfocor > 0.0 ) { - delr1[0] = x[j][0] - xtmp; - delr1[1] = x[j][1] - ytmp; - delr1[2] = x[j][2] - ztmp; - rsq1 = vec3_dot(delr1,delr1); - - if (rsq1 > params[iparam_ij].cutsq) continue; - ++numcoor; - } - NCo[i] = numcoor; - } - } - - // three-body interactions - // skip immediately if I-J is not within cutoff - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - jtype = map[type[j]]; - iparam_ij = elem2param[itype][jtype][jtype]; - - // this Qj for q-dependent BSi - - jq = q[j]; - - delr1[0] = x[j][0] - xtmp; - delr1[1] = x[j][1] - ytmp; - delr1[2] = x[j][2] - ztmp; - rsq1 = vec3_dot(delr1,delr1); - - if (rsq1 > params[iparam_ij].cutsq) continue; - - // accumulate bondorder zeta for each i-j interaction via loop over k - - fjxtmp = fjytmp = fjztmp = 0.0; - zeta_ij = 0.0; - cuo_flag1 = 0; cuo_flag2 = 0; - - for (kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - k = jlist[kk]; - k &= NEIGHMASK; - ktype = map[type[k]]; - iparam_ijk = elem2param[itype][jtype][ktype]; - - delr2[0] = x[k][0] - xtmp; - delr2[1] = x[k][1] - ytmp; - delr2[2] = x[k][2] - ztmp; - rsq2 = vec3_dot(delr2,delr2); - - if (rsq2 > params[iparam_ijk].cutsq) continue; - - zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); - - if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1; - if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1; - } - - if (cuo_flag1 && cuo_flag2) cuo_flag = 1; - else cuo_flag = 0; - - // pairwise force due to zeta - - force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair, - prefactor,EFLAG,evdwl,iq,jq); - - // over-coordination correction for HfO2 - - if (cor_flag && NCo[i] != 0) - Over_cor(¶ms[iparam_ij],rsq1,NCo[i],Eov, Fov); - evdwl += Eov; - fpair += Fov; - - fxtmp += delr1[0]*fpair; - fytmp += delr1[1]*fpair; - fztmp += delr1[2]*fpair; - fjxtmp -= delr1[0]*fpair; - fjytmp -= delr1[1]*fpair; - fjztmp -= delr1[2]*fpair; - - if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0, - -fpair,-delr1[0],-delr1[1],-delr1[2],tid); - - // attractive term via loop over k (3-body forces) - - for (kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - k = jlist[kk]; - k &= NEIGHMASK; - ktype = map[type[k]]; - iparam_ijk = elem2param[itype][jtype][ktype]; - - delr2[0] = x[k][0] - xtmp; - delr2[1] = x[k][1] - ytmp; - delr2[2] = x[k][2] - ztmp; - rsq2 = vec3_dot(delr2,delr2); - if (rsq2 > params[iparam_ijk].cutsq) continue; - - for (rsc = 0; rsc < 3; rsc++) - fi[rsc] = fj[rsc] = fk[rsc] = 0.0; - - attractive(¶ms[iparam_ijk],prefactor, - rsq1,rsq2,delr1,delr2,fi,fj,fk); - - // 3-body LP and BB correction and forces - - elp_ij = elp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); - flp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp); - - fxtmp += fi[0] + filp[0]; - fytmp += fi[1] + filp[1]; - fztmp += fi[2] + filp[2]; - fjxtmp += fj[0] + fjlp[0]; - fjytmp += fj[1] + fjlp[1]; - fjztmp += fj[2] + fjlp[2]; - f[k][0] += fk[0] + fklp[0]; - f[k][1] += fk[1] + fklp[1]; - f[k][2] += fk[2] + fklp[2]; - - if (EVFLAG) - ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, - elp_ij,0.0,0.0,0.0,0.0,0.0, tid); - if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid); - } - f[j][0] += fjxtmp; - f[j][1] += fjytmp; - f[j][2] += fjztmp; - } - f[i][0] += fxtmp; - f[i][1] += fytmp; - f[i][2] += fztmp; - - if (cuo_flag) params[iparam_i].cutsq *= 0.65; - } - cuo_flag = 0; -} - -/* ---------------------------------------------------------------------- */ - -double PairCombOMP::yasu_char(double *qf_fix, int &igroup) -{ - int ii; - double potal,fac11,fac11e; - - const double * const * const x = atom->x; - const double * const q = atom->q; - const int * const type = atom->type; - - const int inum = list->inum; - const int * const ilist = list->ilist; - const int * const numneigh = list->numneigh; - const int * const * const firstneigh = list->firstneigh; - - const int * const mask = atom->mask; - const int groupbit = group->bitmask[igroup]; - - qf = qf_fix; - for (ii = 0; ii < inum; ii++) { - const int i = ilist[ii]; - if (mask[i] & groupbit) - qf[i] = 0.0; - } - - // communicating charge force to all nodes, first forward then reverse - - comm->forward_comm_pair(this); - - // self energy correction term: potal - - potal_calc(potal,fac11,fac11e); - - // loop over full neighbor list of my atoms -#if defined(_OPENMP) -#pragma omp parallel for private(ii) default(none) shared(potal,fac11e) -#endif - for (ii = 0; ii < inum; ii ++) { - double fqi,fqj,fqij,fqji,fqjj,delr1[3],delr2[3]; - double sr1,sr2,sr3; - int mr1,mr2,mr3; - - const int i = ilist[ii]; - - if (mask[i] & groupbit) { - fqi = fqj = fqij = fqji = fqjj = 0.0; // should not be needed. - int itype = map[type[i]]; - const double xtmp = x[i][0]; - const double ytmp = x[i][1]; - const double ztmp = x[i][2]; - const double iq = q[i]; - const int iparam_i = elem2param[itype][itype][itype]; - - // charge force from self energy - - fqi = qfo_self(¶ms[iparam_i],iq,potal); - - // two-body interactions - - const int * const jlist = firstneigh[i]; - const int jnum = numneigh[i]; - - for (int jj = 0; jj < jnum; jj++) { - const int j = jlist[jj] & NEIGHMASK; - const int jtype = map[type[j]]; - double jq = q[j]; - - delr1[0] = x[j][0] - xtmp; - delr1[1] = x[j][1] - ytmp; - delr1[2] = x[j][2] - ztmp; - double rsq1 = vec3_dot(delr1,delr1); - - const int iparam_ij = elem2param[itype][jtype][jtype]; - - // long range q-dependent - - if (rsq1 > params[iparam_ij].lcutsq) continue; - - const int inty = intype[itype][jtype]; - - // polynomial three-point interpolation - - tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype); - - // 1/r charge forces - - qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij); - - // field correction to self energy and charge force - - qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqji,fqjj); - fqi += jq * fqij + fqji; -#if defined(_OPENMP) -#pragma omp atomic -#endif - qf[j] += (iq * fqij + fqjj); - - // polarization field charge force - // three-body interactions - - if (rsq1 > params[iparam_ij].cutsq) continue; - - double zeta_ij = 0.0; - - for (int kk = 0; kk < jnum; kk++) { - if (jj == kk) continue; - const int k = jlist[kk] & NEIGHMASK; - const int ktype = map[type[k]]; - const int iparam_ijk = elem2param[itype][jtype][ktype]; - - delr2[0] = x[k][0] - xtmp; - delr2[1] = x[k][1] - ytmp; - delr2[2] = x[k][2] - ztmp; - const double rsq2 = vec3_dot(delr2,delr2); - - if (rsq2 > params[iparam_ijk].cutsq) continue; - zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2); - } - - // charge force in Aij and Bij - - qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj); - fqi += fqij; -#if defined(_OPENMP) -#pragma omp atomic -#endif - qf[j] += fqjj; - } - -#if defined(_OPENMP) -#pragma omp atomic -#endif - qf[i] += fqi; - - } - } - - comm->reverse_comm_pair(this); - - // sum charge force on each node and return it - - double eneg = 0.0; - for (ii = 0; ii < inum; ii++) { - const int i = ilist[ii]; - if (mask[i] & groupbit) - eneg += qf[i]; - } - double enegtot; - MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world); - return enegtot; -} - -/* ---------------------------------------------------------------------- */ - -double PairCombOMP::memory_usage() -{ - double bytes = memory_usage_thr(); - bytes += PairComb::memory_usage(); - - return bytes; -} diff --git a/src/USER-OMP/pair_comb_omp.h b/src/USER-OMP/pair_comb_omp.h deleted file mode 100644 index 6f020ea9ab..0000000000 --- a/src/USER-OMP/pair_comb_omp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Axel Kohlmeyer (Temple U) -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(comb/omp,PairCombOMP) - -#else - -#ifndef LMP_PAIR_COMB_OMP_H -#define LMP_PAIR_COMB_OMP_H - -#include "pair_comb.h" -#include "thr_omp.h" - -namespace LAMMPS_NS { - -class PairCombOMP : public PairComb, public ThrOMP { - - public: - PairCombOMP(class LAMMPS *); - - virtual void compute(int, int); - virtual double memory_usage(); - - virtual double yasu_char(double *, int &); - - private: - template - void eval(double **f, int ifrom, int ito, int tid); -}; - -} - -#endif -#endif From 49573998e7143c15a448619016a87711dca8ad06 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:15:39 +0000 Subject: [PATCH 193/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7068 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-OMP/pair_rebo_omp.cpp | 33 ------------------------------- src/USER-OMP/pair_rebo_omp.h | 36 ---------------------------------- 2 files changed, 69 deletions(-) delete mode 100644 src/USER-OMP/pair_rebo_omp.cpp delete mode 100644 src/USER-OMP/pair_rebo_omp.h diff --git a/src/USER-OMP/pair_rebo_omp.cpp b/src/USER-OMP/pair_rebo_omp.cpp deleted file mode 100644 index 70b5c4e8ae..0000000000 --- a/src/USER-OMP/pair_rebo_omp.cpp +++ /dev/null @@ -1,33 +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 "pair_rebo_omp.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -PairREBOOMP::PairREBOOMP(LAMMPS *lmp) : PairAIREBOOMP(lmp) {} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairREBOOMP::settings(int narg, char **arg) -{ - if (narg != 0) error->all(FLERR,"Illegal pair_style command"); - - cutlj = 0.0; - ljflag = torflag = 0; -} diff --git a/src/USER-OMP/pair_rebo_omp.h b/src/USER-OMP/pair_rebo_omp.h deleted file mode 100644 index 4606e56ae1..0000000000 --- a/src/USER-OMP/pair_rebo_omp.h +++ /dev/null @@ -1,36 +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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(rebo/omp,PairREBOOMP) - -#else - -#ifndef LMP_PAIR_REBO_OMP_H -#define LMP_PAIR_REBO_OMP_H - -#include "pair_airebo_omp.h" - -namespace LAMMPS_NS { - -class PairREBOOMP : public PairAIREBOOMP { - public: - PairREBOOMP(class LAMMPS *); - virtual void settings(int, char **); -}; - -} - -#endif -#endif From 850a3cf8a4def085ef4d5ca127f050557c5a1be9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:22:23 +0000 Subject: [PATCH 194/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7069 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-OMP/README | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/USER-OMP/README diff --git a/src/USER-OMP/README b/src/USER-OMP/README new file mode 100644 index 0000000000..b200fee478 --- /dev/null +++ b/src/USER-OMP/README @@ -0,0 +1,10 @@ +This package provides OpenMP multi-threading support and other +optimizations of various LAMMPS pair styles, dihedral styles, and fix +styles. + +See this section of the manual to get started: + +doc/Section_accelerate.html, sub-section 5.2 + +The person who created this package is Axel Kohlmeyer at Temple U +(akohlmey at gmail.com). Contact him directly if you have questions. From d2a730bc4031e05ac80017fd352e104c07fd98ba Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 10 Oct 2011 17:29:10 +0000 Subject: [PATCH 195/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7071 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 4fc791ad6b..ca89fa4bf8 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "11 Oct 2011" +#define LAMMPS_VERSION "12 Oct 2011" From d8df399c7f08b0b6adabf1d521f85b41a57b8f28 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 13 Oct 2011 13:31:47 +0000 Subject: [PATCH 196/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7088 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_modify.html | 194 ++++++++++++++++++++++++---------------- doc/Section_modify.txt | 194 ++++++++++++++++++++++++---------------- 2 files changed, 236 insertions(+), 152 deletions(-) diff --git a/doc/Section_modify.html b/doc/Section_modify.html index 8a85bd0c39..8e217b40fe 100644 --- a/doc/Section_modify.html +++ b/doc/Section_modify.html @@ -142,44 +142,49 @@ features that can be added in the manner just described:

      10.1 Atom styles

      -

      Classes that define an atom style are derived from the Atom class. -The atom style determines what quantities are associated with an atom. -A new atom style can be created if one of the existing atom styles -does not define all the arrays you need to store and communicate with -atoms. +

      Classes that define an atom style are derived from the AtomVec class +and managed by the Atom class. The atom style determines what +quantities are associated with an atom. A new atom style can be +created if one of the existing atom styles does not define all +the arrays you need to store and communicate with atoms.

      Atom_vec_atomic.cpp is a simple example of an atom style.

      Here is a brief description of methods you define in your new derived -class. See atom.h for details. +class. See atom_vec.h for details.

      - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      grow re-allocate atom arrays to longer lengths
      copy copy info for one atom to another atom's array locations
      pack_comm store an atom's info in a buffer communicated every timestep
      pack_comm_vel add velocity info to buffer
      pack_comm_one store extra info unique to this atom style
      unpack_comm retrieve an atom's info from the buffer
      unpack_comm_vel also retrieve velocity info
      unpack_comm_one retreive extra info unique to this atom style
      pack_reverse store an atom's info in a buffer communicating partial forces
      pack_reverse_one store extra info unique to this atom style
      unpack_reverse retrieve an atom's info from the buffer
      unpack_reverse_one retreive extra info unique to this atom style
      pack_border store an atom's info in a buffer communicated on neighbor re-builds
      pack_border_vel add velocity info to buffer
      pack_border_one store extra info unique to this atom style
      unpack_border retrieve an atom's info from the buffer
      unpack_border_vel also retrieve velocity info
      unpack_border_one retreive extra info unique to this atom style
      pack_exchange store all an atom's info to migrate to another processor
      unpack_exchange retrieve an atom's info from the buffer
      size_restart number of restart quantities associated with proc's atoms
      pack_restart pack atom quantities into a buffer
      unpack_restart unpack atom quantities from a buffer
      create_atom create an individual atom of this style
      data_atom parse an atom line from the data file
      memory_usage tally memory allocated by atom arrays +
      init one time setup (optional)
      grow re-allocate atom arrays to longer lengths (required)
      grow_reset make array pointers in Atom and AtomVec classes consistent (required)
      copy copy info for one atom to another atom's array locations (required)
      pack_comm store an atom's info in a buffer communicated every timestep (required)
      pack_comm_vel add velocity info to communication buffer (required)
      pack_comm_hybrid store extra info unique to this atom style (optional)
      unpack_comm retrieve an atom's info from the buffer (required)
      unpack_comm_vel also retrieve velocity info (required)
      unpack_comm_hybrid retreive extra info unique to this atom style (optional)
      pack_reverse store an atom's info in a buffer communicating partial forces (required)
      pack_reverse_hybrid store extra info unique to this atom style (optional)
      unpack_reverse retrieve an atom's info from the buffer (required)
      unpack_reverse_hybrid retreive extra info unique to this atom style (optional)
      pack_border store an atom's info in a buffer communicated on neighbor re-builds (required)
      pack_border_vel add velocity info to buffer (required)
      pack_border_hybrid store extra info unique to this atom style (optional)
      unpack_border retrieve an atom's info from the buffer (required)
      unpack_border_vel also retrieve velocity info (required)
      unpack_border_hybrid retreive extra info unique to this atom style (optional)
      pack_exchange store all an atom's info to migrate to another processor (required)
      unpack_exchange retrieve an atom's info from the buffer (required)
      size_restart number of restart quantities associated with proc's atoms (required)
      pack_restart pack atom quantities into a buffer (required)
      unpack_restart unpack atom quantities from a buffer (required)
      create_atom create an individual atom of this style (required)
      data_atom parse an atom line from the data file (required)
      data_atom_hybrid parse additional atom info unique to this atom style (optional)
      data_vel parse one line of velocity information from data file (optional)
      data_vel_hybrid parse additional velocity data unique to this atom style (optional)
      memory_usage tally memory allocated by atom arrays (required)

      The constructor of the derived class sets values for several variables @@ -200,16 +205,21 @@ add new potentials to LAMMPS. the harmonic forms of the angle, dihedral, and improper style commands.

      -

      Here is a brief description of methods you define in your new derived -bond class. See bond.h, angle.h, dihedral.h, and improper.h for -details. +

      Here is a brief description of common methods you define in your +new derived class. See bond.h, angle.h, dihedral.h, and improper.h +for details and specific additional methods.

      - - - - - + + + + + + + + +
      compute compute the molecular interactions
      coeff set coefficients for one bond type
      equilibrium_distance length of bond, used by SHAKE
      write & read_restart writes/reads coeffs to restart files
      single force and energy of a single bond +
      init check if all coefficients are set, calls init_style (optional)
      init_style check if style specific conditions are met (optional)
      compute compute the molecular interactions (required)
      settings apply global settings for all types (optional)
      coeff set coefficients for one type (required)
      equilibrium_distance length of bond, used by SHAKE (required, bond only)
      equilibrium_angle opening of angle, used by SHAKE (required, angle only)
      write & read_restart writes/reads coeffs to restart files (required)
      single force and energy of a single bond or angle (required, bond or angle only)
      memory_usage tally memory allocated by the style (optional)

      @@ -230,14 +240,21 @@ per-atom kinetic energy. class. See compute.h for details.

      - - - - - - - - + + + + + + + + + + + + + +
      compute_scalar compute a scalar quantity
      compute_vector compute a vector of quantities
      compute_peratom compute one or more quantities per atom
      pack_comm pack a buffer with items to communicate
      unpack_comm unpack the buffer
      pack_reverse pack a buffer with items to reverse communicate
      unpack_reverse unpack the buffer
      memory_usage tally memory usage +
      init perform one time setup (required)
      init_list neighbor list setup, if needed (optional)
      compute_scalar compute a scalar quantity (optional)
      compute_vector compute a vector of quantities (optional)
      compute_peratom compute one or more quantities per atom (optional)
      compute_local compute one or more quantities per processor (optional)
      pack_comm pack a buffer with items to communicate (optional)
      unpack_comm unpack the buffer (optional)
      pack_reverse pack a buffer with items to reverse communicate (optional)
      unpack_reverse unpack the buffer (optional)
      remove_bias remove velocity bias from one atom (optional)
      remove_bias_all remove velocity bias from all atoms in group (optional)
      restore_bias restore velocity bias for one atom after remove_bias (optional)
      restore_bias_all same as before, but for all atoms in group (optional)
      memory_usage tally memory usage (optional)

      @@ -295,34 +312,59 @@ implement. derived class. See fix.h for details.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      setmask determines when the fix is called during the timestep
      init initialization before a run
      setup called immediately before the 1st timestep
      initial_integrate called at very beginning of each timestep
      pre_exchange called before atom exchange on re-neighboring steps
      pre_neighbor called before neighbor list build
      post_force called after pair & molecular forces are computed
      final_integrate called at end of each timestep
      end_of_step called at very end of timestep
      write_restart dumps fix info to restart file
      restart uses info from restart file to re-initialize the fix
      grow_arrays allocate memory for atom-based arrays used by fix
      copy_arrays copy atom info when an atom migrates to a new processor
      memory_usage report memory used by fix
      pack_exchange store atom's data in a buffer
      unpack_exchange retrieve atom's data from a buffer
      pack_restart store atom's data for writing to restart file
      unpack_restart retrieve atom's data from a restart file buffer
      size_restart size of atom's data
      maxsize_restart max size of atom's data
      initial_integrate_respa same as initial_integrate, but for rRESPA
      post_force_respa same as post_force, but for rRESPA
      final_integrate_respa same as final_integrate, but for rRESPA
      pack_comm pack a buffer to communicate a per-atom quantity
      unpack_comm unpack a buffer to communicate a per-atom quantity
      pack_reverse_comm pack a buffer to reverse communicate a per-atom quantity
      unpack_reverse_comm unpack a buffer to reverse communicate a per-atom quantity
      thermo compute quantities for thermodynamic output +
      setmask determines when the fix is called during the timestep (required)
      init initialization before a run (optional)
      setup_pre_exchange called before atom exchange in setup (optional)
      setup_pre_force called before force computation in setup (optional)
      setup called immediately before the 1st timestep and after forces are computed (optional)
      min_setup_pre_force like setup_pre_force, but for minimizations instead of MD runs (optional)
      min_setup like setup, but for minimizations instead of MD runs (optional)
      initial_integrate called at very beginning of each timestep (optional)
      pre_exchange called before atom exchange on re-neighboring steps (optional)
      pre_neighbor called before neighbor list build (optional)
      pre_force called after pair & molecular forces are computed (optional)
      post_force called after pair & molecular forces are computed and communicated (optional)
      final_integrate called at end of each timestep (optional)
      end_of_step called at very end of timestep (optional)
      write_restart dumps fix info to restart file (optional)
      restart uses info from restart file to re-initialize the fix (optional)
      grow_arrays allocate memory for atom-based arrays used by fix (optional)
      copy_arrays copy atom info when an atom migrates to a new processor (optional)
      pack_exchange store atom's data in a buffer (optional)
      unpack_exchange retrieve atom's data from a buffer (optional)
      pack_restart store atom's data for writing to restart file (optional)
      unpack_restart retrieve atom's data from a restart file buffer (optional)
      size_restart size of atom's data (optional)
      maxsize_restart max size of atom's data (optional)
      setup_pre_force_respa same as setup_pre_force, but for rRESPA (optional)
      initial_integrate_respa same as initial_integrate, but for rRESPA (optional)
      post_integrate_respa called after the first half integration step is done in rRESPA (optional)
      pre_force_respa same as pre_force, but for rRESPA (optional)
      post_force_respa same as post_force, but for rRESPA (optional)
      final_integrate_respa same as final_integrate, but for rRESPA (optional)
      min_pre_force called after pair & molecular forces are computed in minimizer (optional)
      min_post_force called after pair & molecular forces are computed and communicated in minmizer (optional)
      min_store store extra data for linesearch based minimization on a LIFO stack (optional)
      min_pushstore push the minimization LIFO stack one element down (optional)
      min_popstore pop the minimization LIFO stack one element up (optional)
      min_clearstore clear minimization LIFO stack (optional)
      min_step reset or move forward on line search minimization (optional)
      min_dof report number of degrees of freedom added by this fix in minimization (optional)
      max_alpha report maximum allowed step size during linesearch minimization (optional)
      pack_comm pack a buffer to communicate a per-atom quantity (optional)
      unpack_comm unpack a buffer to communicate a per-atom quantity (optional)
      pack_reverse_comm pack a buffer to reverse communicate a per-atom quantity (optional)
      unpack_reverse_comm unpack a buffer to reverse communicate a per-atom quantity (optional)
      dof report number of degrees of freedom removed by this fix during MD (optional)
      compute_scalar return a global scalar property that the fix computes (optional)
      compute_vector return a component of a vector property that the fix computes (optional)
      compute_array return a component of an array property that the fix computes (optional)
      deform called when the box size is changed (optional)
      reset_target called when a change of the target temperature is requested during a run (optional)
      reset_dt is called when a change of the time step is requested during a run (optional)
      modify_param called when a fix_modify request is executed (optional)
      memory_usage report memory used by fix (optional)
      thermo compute quantities for thermodynamic output (optional)

      Typically, only a small fraction of these methods are defined for a diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt index 662a1729a8..789761cbb2 100644 --- a/doc/Section_modify.txt +++ b/doc/Section_modify.txt @@ -140,43 +140,48 @@ features that can be added in the manner just described: 10.1 Atom styles :link(mod_1),h4 -Classes that define an atom style are derived from the Atom class. -The atom style determines what quantities are associated with an atom. -A new atom style can be created if one of the existing atom styles -does not define all the arrays you need to store and communicate with -atoms. +Classes that define an atom style are derived from the AtomVec class +and managed by the Atom class. The atom style determines what +quantities are associated with an atom. A new atom style can be +created if one of the existing atom styles does not define all +the arrays you need to store and communicate with atoms. Atom_vec_atomic.cpp is a simple example of an atom style. Here is a brief description of methods you define in your new derived -class. See atom.h for details. +class. See atom_vec.h for details. -grow: re-allocate atom arrays to longer lengths -copy: copy info for one atom to another atom's array locations -pack_comm: store an atom's info in a buffer communicated every timestep -pack_comm_vel: add velocity info to buffer -pack_comm_one: store extra info unique to this atom style -unpack_comm: retrieve an atom's info from the buffer -unpack_comm_vel: also retrieve velocity info -unpack_comm_one: retreive extra info unique to this atom style -pack_reverse: store an atom's info in a buffer communicating partial forces -pack_reverse_one: store extra info unique to this atom style -unpack_reverse: retrieve an atom's info from the buffer -unpack_reverse_one: retreive extra info unique to this atom style -pack_border: store an atom's info in a buffer communicated on neighbor re-builds -pack_border_vel: add velocity info to buffer -pack_border_one: store extra info unique to this atom style -unpack_border: retrieve an atom's info from the buffer -unpack_border_vel: also retrieve velocity info -unpack_border_one: retreive extra info unique to this atom style -pack_exchange: store all an atom's info to migrate to another processor -unpack_exchange: retrieve an atom's info from the buffer -size_restart: number of restart quantities associated with proc's atoms -pack_restart: pack atom quantities into a buffer -unpack_restart: unpack atom quantities from a buffer -create_atom: create an individual atom of this style -data_atom: parse an atom line from the data file -memory_usage: tally memory allocated by atom arrays :tb(s=:) +init: one time setup (optional) +grow: re-allocate atom arrays to longer lengths (required) +grow_reset: make array pointers in Atom and AtomVec classes consistent (required) +copy: copy info for one atom to another atom's array locations (required) +pack_comm: store an atom's info in a buffer communicated every timestep (required) +pack_comm_vel: add velocity info to communication buffer (required) +pack_comm_hybrid: store extra info unique to this atom style (optional) +unpack_comm: retrieve an atom's info from the buffer (required) +unpack_comm_vel: also retrieve velocity info (required) +unpack_comm_hybrid: retreive extra info unique to this atom style (optional) +pack_reverse: store an atom's info in a buffer communicating partial forces (required) +pack_reverse_hybrid: store extra info unique to this atom style (optional) +unpack_reverse: retrieve an atom's info from the buffer (required) +unpack_reverse_hybrid: retreive extra info unique to this atom style (optional) +pack_border: store an atom's info in a buffer communicated on neighbor re-builds (required) +pack_border_vel: add velocity info to buffer (required) +pack_border_hybrid: store extra info unique to this atom style (optional) +unpack_border: retrieve an atom's info from the buffer (required) +unpack_border_vel: also retrieve velocity info (required) +unpack_border_hybrid: retreive extra info unique to this atom style (optional) +pack_exchange: store all an atom's info to migrate to another processor (required) +unpack_exchange: retrieve an atom's info from the buffer (required) +size_restart: number of restart quantities associated with proc's atoms (required) +pack_restart: pack atom quantities into a buffer (required) +unpack_restart: unpack atom quantities from a buffer (required) +create_atom: create an individual atom of this style (required) +data_atom: parse an atom line from the data file (required) +data_atom_hybrid: parse additional atom info unique to this atom style (optional) +data_vel: parse one line of velocity information from data file (optional) +data_vel_hybrid: parse additional velocity data unique to this atom style (optional) +memory_usage: tally memory allocated by atom arrays (required) :tb(s=:) The constructor of the derived class sets values for several variables that you must set when defining a new atom style, which are documented @@ -196,15 +201,20 @@ Bond_harmonic.cpp is the simplest example of a bond style. Ditto for the harmonic forms of the angle, dihedral, and improper style commands. -Here is a brief description of methods you define in your new derived -bond class. See bond.h, angle.h, dihedral.h, and improper.h for -details. +Here is a brief description of common methods you define in your +new derived class. See bond.h, angle.h, dihedral.h, and improper.h +for details and specific additional methods. -compute: compute the molecular interactions -coeff: set coefficients for one bond type -equilibrium_distance: length of bond, used by SHAKE -write & read_restart: writes/reads coeffs to restart files -single: force and energy of a single bond :tb(s=:) +init: check if all coefficients are set, calls {init_style} (optional) +init_style: check if style specific conditions are met (optional) +compute: compute the molecular interactions (required) +settings: apply global settings for all types (optional) +coeff: set coefficients for one type (required) +equilibrium_distance: length of bond, used by SHAKE (required, bond only) +equilibrium_angle: opening of angle, used by SHAKE (required, angle only) +write & read_restart: writes/reads coeffs to restart files (required) +single: force and energy of a single bond or angle (required, bond or angle only) +memory_usage: tally memory allocated by the style (optional) :tb(s=:) :line @@ -223,14 +233,21 @@ per-atom kinetic energy. Here is a brief description of methods you define in your new derived class. See compute.h for details. -compute_scalar: compute a scalar quantity -compute_vector: compute a vector of quantities -compute_peratom: compute one or more quantities per atom -pack_comm: pack a buffer with items to communicate -unpack_comm: unpack the buffer -pack_reverse: pack a buffer with items to reverse communicate -unpack_reverse: unpack the buffer -memory_usage: tally memory usage :tb(s=:) +init: perform one time setup (required) +init_list: neighbor list setup, if needed (optional) +compute_scalar: compute a scalar quantity (optional) +compute_vector: compute a vector of quantities (optional) +compute_peratom: compute one or more quantities per atom (optional) +compute_local: compute one or more quantities per processor (optional) +pack_comm: pack a buffer with items to communicate (optional) +unpack_comm: unpack the buffer (optional) +pack_reverse: pack a buffer with items to reverse communicate (optional) +unpack_reverse: unpack the buffer (optional) +remove_bias: remove velocity bias from one atom (optional) +remove_bias_all: remove velocity bias from all atoms in group (optional) +restore_bias: restore velocity bias for one atom after remove_bias (optional) +restore_bias_all: same as before, but for all atoms in group (optional) +memory_usage: tally memory usage (optional) :tb(s=:) :line @@ -283,34 +300,59 @@ implement. Here is a brief description of methods you can define in your new derived class. See fix.h for details. -setmask: determines when the fix is called during the timestep -init: initialization before a run -setup: called immediately before the 1st timestep -initial_integrate: called at very beginning of each timestep -pre_exchange: called before atom exchange on re-neighboring steps -pre_neighbor: called before neighbor list build -post_force: called after pair & molecular forces are computed -final_integrate: called at end of each timestep -end_of_step: called at very end of timestep -write_restart: dumps fix info to restart file -restart: uses info from restart file to re-initialize the fix -grow_arrays: allocate memory for atom-based arrays used by fix -copy_arrays: copy atom info when an atom migrates to a new processor -memory_usage: report memory used by fix -pack_exchange: store atom's data in a buffer -unpack_exchange: retrieve atom's data from a buffer -pack_restart: store atom's data for writing to restart file -unpack_restart: retrieve atom's data from a restart file buffer -size_restart: size of atom's data -maxsize_restart: max size of atom's data -initial_integrate_respa: same as initial_integrate, but for rRESPA -post_force_respa: same as post_force, but for rRESPA -final_integrate_respa: same as final_integrate, but for rRESPA -pack_comm: pack a buffer to communicate a per-atom quantity -unpack_comm: unpack a buffer to communicate a per-atom quantity -pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity -unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity -thermo: compute quantities for thermodynamic output :tb(s=:) +setmask: determines when the fix is called during the timestep (required) +init: initialization before a run (optional) +setup_pre_exchange: called before atom exchange in setup (optional) +setup_pre_force: called before force computation in setup (optional) +setup: called immediately before the 1st timestep and after forces are computed (optional) +min_setup_pre_force: like setup_pre_force, but for minimizations instead of MD runs (optional) +min_setup: like setup, but for minimizations instead of MD runs (optional) +initial_integrate: called at very beginning of each timestep (optional) +pre_exchange: called before atom exchange on re-neighboring steps (optional) +pre_neighbor: called before neighbor list build (optional) +pre_force: called after pair & molecular forces are computed (optional) +post_force: called after pair & molecular forces are computed and communicated (optional) +final_integrate: called at end of each timestep (optional) +end_of_step: called at very end of timestep (optional) +write_restart: dumps fix info to restart file (optional) +restart: uses info from restart file to re-initialize the fix (optional) +grow_arrays: allocate memory for atom-based arrays used by fix (optional) +copy_arrays: copy atom info when an atom migrates to a new processor (optional) +pack_exchange: store atom's data in a buffer (optional) +unpack_exchange: retrieve atom's data from a buffer (optional) +pack_restart: store atom's data for writing to restart file (optional) +unpack_restart: retrieve atom's data from a restart file buffer (optional) +size_restart: size of atom's data (optional) +maxsize_restart: max size of atom's data (optional) +setup_pre_force_respa: same as setup_pre_force, but for rRESPA (optional) +initial_integrate_respa: same as initial_integrate, but for rRESPA (optional) +post_integrate_respa: called after the first half integration step is done in rRESPA (optional) +pre_force_respa: same as pre_force, but for rRESPA (optional) +post_force_respa: same as post_force, but for rRESPA (optional) +final_integrate_respa: same as final_integrate, but for rRESPA (optional) +min_pre_force: called after pair & molecular forces are computed in minimizer (optional) +min_post_force: called after pair & molecular forces are computed and communicated in minmizer (optional) +min_store: store extra data for linesearch based minimization on a LIFO stack (optional) +min_pushstore: push the minimization LIFO stack one element down (optional) +min_popstore: pop the minimization LIFO stack one element up (optional) +min_clearstore: clear minimization LIFO stack (optional) +min_step: reset or move forward on line search minimization (optional) +min_dof: report number of degrees of freedom {added} by this fix in minimization (optional) +max_alpha: report maximum allowed step size during linesearch minimization (optional) +pack_comm: pack a buffer to communicate a per-atom quantity (optional) +unpack_comm: unpack a buffer to communicate a per-atom quantity (optional) +pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity (optional) +unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity (optional) +dof: report number of degrees of freedom {removed} by this fix during MD (optional) +compute_scalar: return a global scalar property that the fix computes (optional) +compute_vector: return a component of a vector property that the fix computes (optional) +compute_array: return a component of an array property that the fix computes (optional) +deform: called when the box size is changed (optional) +reset_target: called when a change of the target temperature is requested during a run (optional) +reset_dt: is called when a change of the time step is requested during a run (optional) +modify_param: called when a fix_modify request is executed (optional) +memory_usage: report memory used by fix (optional) +thermo: compute quantities for thermodynamic output (optional) :tb(s=:) Typically, only a small fraction of these methods are defined for a particular fix. Setmask is mandatory, as it determines when the fix From eae3431926f0e6ab48cc024ac4d35fee2d6cd4bd Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 14 Oct 2011 20:16:41 +0000 Subject: [PATCH 197/246] Added note about omega git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7091 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_tersoff.html | 2 +- doc/pair_tersoff.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html index 96f629494a..ecab9b3a4f 100644 --- a/doc/pair_tersoff.html +++ b/doc/pair_tersoff.html @@ -133,7 +133,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2 potential (Tersoff_2).

      LAMMPS parameter values for Tersoff_2 can be obtained as follows: -gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of +gamma_ijk = omega_ik, lambda3 = 0 and the value of m has no effect. The parameters for species i and j can be calculated using the Tersoff_2 mixing rules:

      diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt index 2f0f539e95..7150c06b91 100644 --- a/doc/pair_tersoff.txt +++ b/doc/pair_tersoff.txt @@ -129,7 +129,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2 potential "(Tersoff_2)"_#Tersoff_2. LAMMPS parameter values for Tersoff_2 can be obtained as follows: -gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of +gamma_ijk = omega_ik, lambda3 = 0 and the value of m has no effect. The parameters for species i and j can be calculated using the Tersoff_2 mixing rules: From df52f93e5ebfb1dd3602520060b01e803a87ed25 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 17 Oct 2011 15:22:40 +0000 Subject: [PATCH 198/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7098 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/set.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/set.cpp b/src/set.cpp index 507fa812f5..4e76dfa2b4 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -28,9 +28,8 @@ #include "pair.h" #include "random_park.h" #include "math_extra.h" -#include "error.h" - #include "math_const.h" +#include "error.h" using namespace LAMMPS_NS; using namespace MathConst; @@ -95,7 +94,8 @@ void Set::command(int narg, char **arg) error->all(FLERR,"Invalid value in set command"); if (fraction < 0.0 || fraction > 1.0) error->all(FLERR,"Invalid value in set command"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); setrandom(TYPE_FRACTION); iarg += 4; } else if (strcmp(arg[iarg],"mol") == 0) { @@ -165,8 +165,10 @@ void Set::command(int narg, char **arg) dvalue = atof(arg[iarg+2]); if (!atom->mu_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); - if (dvalue <= 0.0) error->all(FLERR,"Invalid dipole length in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); + if (dvalue <= 0.0) + error->all(FLERR,"Invalid dipole length in set command"); setrandom(DIPOLE_RANDOM); iarg += 3; } else if (strcmp(arg[iarg],"quat") == 0) { @@ -184,7 +186,8 @@ void Set::command(int narg, char **arg) ivalue = atoi(arg[iarg+1]); if (!atom->ellipsoid_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"diameter") == 0) { @@ -225,11 +228,14 @@ void Set::command(int narg, char **arg) zimage = atoi(arg[iarg+3]); } if (ximageflag && ximage && !domain->xperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); if (yimageflag && yimage && !domain->yperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); if (zimageflag && zimage && !domain->zperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); set(IMAGE); iarg += 4; } else if (strcmp(arg[iarg],"bond") == 0) { @@ -444,7 +450,8 @@ void Set::set(int keyword) } else if (keyword == QUAT) { if (atom->ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom that is not an ellipsoid"); + error->one(FLERR, + "Cannot set quaternion for atom that is not an ellipsoid"); double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; double theta2 = MY_PI2 * wvalue/180.0; double sintheta2 = sin(theta2); From 55b951bed074302482b7037f8ba7e33cf76f6d8e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 19 Oct 2011 22:43:40 +0000 Subject: [PATCH 199/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7128 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/compute_property_atom.html | 11 ++++++----- doc/compute_property_atom.txt | 11 ++++++----- doc/read_data.html | 13 +++++-------- doc/read_data.txt | 8 +++----- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/doc/compute_property_atom.html b/doc/compute_property_atom.html index 6390d3e029..aec547b978 100644 --- a/doc/compute_property_atom.html +++ b/doc/compute_property_atom.html @@ -79,12 +79,13 @@ additional quantities that are only defined for certain dump custom command are as follows. +

      The additional quantities only accessible via this command, and not +directly via the dump custom command, are as follows.

      Shapex, shapey, and shapez are defined for ellipsoidal particles and define the 3d shape of each particle. Quatw, quati, quatj, diff --git a/doc/compute_property_atom.txt b/doc/compute_property_atom.txt index bae2846f4e..f2a088be34 100644 --- a/doc/compute_property_atom.txt +++ b/doc/compute_property_atom.txt @@ -72,12 +72,13 @@ additional quantities that are only defined for certain "atom styles"_atom_style.html. Basically, this list gives your input script access to any per-atom quantity stored by LAMMPS. -The values are stored in a per-atom vector or array as -discussed below. Zeroes are stored for atoms not in the specified -group. +The values are stored in a per-atom vector or array as discussed +below. Zeroes are stored for atoms not in the specified group or for +quantities that are not defined for a particular particle in the group +(e.g. {shapex} if the particle is not an ellipsoid). -The additional quantities only accessible via this command (and not -directly via the "dump custom"_dump.html command are as follows. +The additional quantities only accessible via this command, and not +directly via the "dump custom"_dump.html command, are as follows. {Shapex}, {shapey}, and {shapez} are defined for ellipsoidal particles and define the 3d shape of each particle. {Quatw}, {quati}, {quatj}, diff --git a/doc/read_data.html b/doc/read_data.html index bd2e87918f..2eced78fe0 100644 --- a/doc/read_data.html +++ b/doc/read_data.html @@ -159,7 +159,7 @@ space in LAMMPS data structures for storing the new bonds.

      The "ellipsoids setting is only used with atom_style ellipsoid and specifies how many of the atoms are finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipseflag and the Ellipsoids section below. +discussion of ellipsoidflag and the Ellipsoids section below.


      @@ -342,7 +342,7 @@ keep track of molecule assignments.

      The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle.

      -

      The ellipseflag determines whether the particle is a finite-size +

      The ellipsoidflag determines whether the particle is a finite-size ellipsoid of finite size, or a point particle. Additional attributes must be defined for each ellipsoid in the Ellipsoids section.

      @@ -530,15 +530,12 @@ section must be integers (1, not 1.0).
    • line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk -
        atom-ID = ID of atom which is an ellipsoid
      +
    • atom-ID = ID of atom which is an ellipsoid shapex,shapey,shapez = 3 diameters of ellipsoid (distance units) quatw,quati,quatj,quatk = quaternion components for orientation of atom -type = bond type (1-Nbondtype) - atom1,atom2 = IDs of 1st,2nd atoms in bond -
    • -
    • example: +example: -
        12 3 17 29 
      +
        12 1 2 1 1 0 0 0 
       
    diff --git a/doc/read_data.txt b/doc/read_data.txt index e2d1c0437c..d023d5de6e 100644 --- a/doc/read_data.txt +++ b/doc/read_data.txt @@ -156,7 +156,7 @@ space in LAMMPS data structures for storing the new bonds. The "ellipsoids" setting is only used with atom_style ellipsoid"_atom_style.html and specifies how many of the atoms are finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipseflag and the {Ellipsoids} section below. +discussion of ellipsoidflag and the {Ellipsoids} section below. :line @@ -321,7 +321,7 @@ keep track of molecule assignments. The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle. -The ellipseflag determines whether the particle is a finite-size +The ellipsoidflag determines whether the particle is a finite-size ellipsoid of finite size, or a point particle. Additional attributes must be defined for each ellipsoid in the {Ellipsoids} section. @@ -481,10 +481,8 @@ line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk :l atom-ID = ID of atom which is an ellipsoid shapex,shapey,shapez = 3 diameters of ellipsoid (distance units) quatw,quati,quatj,quatk = quaternion components for orientation of atom -type = bond type (1-Nbondtype) - atom1,atom2 = IDs of 1st,2nd atoms in bond :pre example: :l - 12 3 17 29 :pre + 12 1 2 1 1 0 0 0 :pre :ule The {Ellipsoids} section must appear if "atom_style From f90ce18f3db4c688d7bf07cc17bf21d0e11cd250 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 00:11:49 +0000 Subject: [PATCH 200/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7133 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/CLASS2/angle_class2.cpp | 4 ++- src/CLASS2/dihedral_class2.cpp | 21 +++++++------- src/CLASS2/dihedral_class2.h | 1 - src/CLASS2/improper_class2.cpp | 15 +++++----- src/CLASS2/improper_class2.h | 1 - src/CLASS2/pair_lj_class2.cpp | 7 +++-- src/CLASS2/pair_lj_class2_coul_cut.cpp | 7 +++-- src/CLASS2/pair_lj_class2_coul_long.cpp | 7 +++-- src/COLLOID/pair_lubricate.cpp | 15 +++++----- src/GPU/pppm_gpu.cpp | 6 ++-- src/GRANULAR/fix_pour.cpp | 12 ++++---- src/GRANULAR/fix_pour.h | 1 - src/GRANULAR/fix_wall_gran.cpp | 7 ++--- src/KSPACE/ewald.cpp | 24 ++++++++-------- src/KSPACE/ewald.h | 1 - src/KSPACE/pair_born_coul_long.cpp | 7 +++-- src/KSPACE/pair_buck_coul_long.cpp | 7 +++-- src/KSPACE/pair_lj_cut_coul_long.cpp | 7 +++-- src/MANYBODY/pair_airebo.cpp | 8 +++--- src/MANYBODY/pair_airebo.h | 1 - src/MANYBODY/pair_comb.cpp | 33 ++++++++++------------ src/MANYBODY/pair_comb.h | 1 - src/MC/fix_gcmc.cpp | 5 ++-- src/MOLECULE/angle_charmm.cpp | 4 ++- src/MOLECULE/angle_cosine.cpp | 4 ++- src/MOLECULE/angle_cosine_periodic.cpp | 4 ++- src/MOLECULE/angle_cosine_squared.cpp | 4 ++- src/MOLECULE/angle_harmonic.cpp | 4 ++- src/MOLECULE/angle_table.cpp | 12 ++++---- src/MOLECULE/dihedral_charmm.cpp | 13 ++++----- src/MOLECULE/dihedral_helix.cpp | 6 ++-- src/MOLECULE/improper_harmonic.cpp | 4 ++- src/MOLECULE/improper_umbrella.cpp | 4 ++- src/MOLECULE/pair_hbond_dreiding_lj.cpp | 14 ++++----- src/MOLECULE/pair_hbond_dreiding_lj.h | 1 - src/MOLECULE/pair_hbond_dreiding_morse.cpp | 10 ++++--- src/SRD/fix_srd.cpp | 12 ++++---- src/USER-CG-CMM/angle_cg_cmm.cpp | 4 ++- src/USER-CG-CMM/pair_cmm_common.cpp | 7 +++-- src/USER-CUDA/fix_gravity_cuda.cpp | 8 +++--- src/USER-CUDA/fix_shake_cuda.cpp | 5 ++-- src/USER-CUDA/fix_shake_cuda.h | 1 - src/USER-CUDA/pppm_cuda.cpp | 21 +++++++------- src/USER-EFF/atom_vec_electron.h | 1 - src/USER-OMP/dihedral_helix_omp.cpp | 6 ++-- src/USER-OMP/pair_soft_omp.cpp | 4 ++- src/angle.cpp | 4 +-- src/angle.h | 2 -- src/atom_vec_ellipsoid.cpp | 6 ++-- src/atom_vec_ellipsoid.h | 1 - src/atom_vec_sphere.cpp | 10 +++---- src/atom_vec_sphere.h | 1 - src/compute_angle_local.cpp | 5 ++-- src/compute_dihedral_local.cpp | 6 ++-- src/compute_improper_local.cpp | 6 ++-- src/compute_rdf.cpp | 7 +++-- src/dihedral.cpp | 1 - src/dihedral.h | 2 -- src/dump_image.cpp | 32 ++++++++++----------- src/dump_image.h | 2 -- src/fix_adapt.cpp | 9 ++++-- src/fix_deform.cpp | 4 ++- src/fix_gravity.cpp | 5 ++-- src/fix_move.cpp | 7 ++--- src/fix_orient_fcc.cpp | 9 +++--- src/fix_orient_fcc.h | 1 - src/fix_restrain.cpp | 5 ++-- src/fix_shake.cpp | 6 ++-- src/fix_shake.h | 1 - src/improper.cpp | 1 - src/improper.h | 2 -- src/pair_born.cpp | 7 +++-- src/pair_buck.cpp | 7 +++-- src/pair_buck_coul_cut.cpp | 7 +++-- src/pair_lj96_cut.cpp | 7 +++-- src/pair_lj_cut.cpp | 7 +++-- src/pair_lj_cut_coul_cut.cpp | 7 +++-- src/pair_lj_expand.cpp | 7 +++-- src/pair_soft.cpp | 15 +++++----- src/pair_soft.h | 1 - src/set.h | 1 - src/thermo.cpp | 10 +++---- src/thermo.h | 2 -- 83 files changed, 293 insertions(+), 271 deletions(-) diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp index ca69cca5b2..ac74f441f7 100644 --- a/src/CLASS2/angle_class2.cpp +++ b/src/CLASS2/angle_class2.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -318,7 +320,7 @@ void AngleClass2::coeff(int narg, char **arg) // convert theta0 from degrees to radians for (int i = ilo; i <= ihi; i++) { - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; k2[i] = k2_one; k3[i] = k3_one; k4[i] = k4_one; diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp index d6e31696d7..f9c04126d8 100644 --- a/src/CLASS2/dihedral_class2.cpp +++ b/src/CLASS2/dihedral_class2.cpp @@ -26,20 +26,19 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.0000001 /* ---------------------------------------------------------------------- */ -DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) -{ - PI = 4.0*atan(1.0); -} +DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) {} /* ---------------------------------------------------------------------- */ @@ -697,8 +696,8 @@ void DihedralClass2::coeff(int narg, char **arg) at_f1_2[i] = f1_2_one; at_f2_2[i] = f2_2_one; at_f3_2[i] = f3_2_one; - at_theta0_1[i] = theta0_1_one/180.0 * PI; - at_theta0_2[i] = theta0_2_one/180.0 * PI; + at_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + at_theta0_2[i] = theta0_2_one/180.0 * MY_PI; setflag_at[i] = 1; count++; } @@ -714,8 +713,8 @@ void DihedralClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { aat_k[i] = k_one; - aat_theta0_1[i] = theta0_1_one/180.0 * PI; - aat_theta0_2[i] = theta0_2_one/180.0 * PI; + aat_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + aat_theta0_2[i] = theta0_2_one/180.0 * MY_PI; setflag_aat[i] = 1; count++; } @@ -749,11 +748,11 @@ void DihedralClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k1[i] = k1_one; - phi1[i] = phi1_one/180.0 * PI; + phi1[i] = phi1_one/180.0 * MY_PI; k2[i] = k2_one; - phi2[i] = phi2_one/180.0 * PI; + phi2[i] = phi2_one/180.0 * MY_PI; k3[i] = k3_one; - phi3[i] = phi3_one/180.0 * PI; + phi3[i] = phi3_one/180.0 * MY_PI; setflag_d[i] = 1; count++; } diff --git a/src/CLASS2/dihedral_class2.h b/src/CLASS2/dihedral_class2.h index c99258a627..b7a519a27d 100644 --- a/src/CLASS2/dihedral_class2.h +++ b/src/CLASS2/dihedral_class2.h @@ -46,7 +46,6 @@ class DihedralClass2 : public Dihedral { double *bb13t_k,*bb13t_r10,*bb13t_r30; int *setflag_d,*setflag_mbt,*setflag_ebt; int *setflag_at,*setflag_aat,*setflag_bb13t; - double PI; void allocate(); }; diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp index 7329870aec..c1331c607e 100644 --- a/src/CLASS2/improper_class2.cpp +++ b/src/CLASS2/improper_class2.cpp @@ -26,19 +26,18 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 /* ---------------------------------------------------------------------- */ -ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) -{ - PI = 4.0*atan(1.0); -} +ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) {} /* ---------------------------------------------------------------------- */ @@ -550,9 +549,9 @@ void ImproperClass2::coeff(int narg, char **arg) aa_k1[i] = k1_one; aa_k2[i] = k2_one; aa_k3[i] = k3_one; - aa_theta0_1[i] = theta0_1_one/180.0 * PI; - aa_theta0_2[i] = theta0_2_one/180.0 * PI; - aa_theta0_3[i] = theta0_3_one/180.0 * PI; + aa_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + aa_theta0_2[i] = theta0_2_one/180.0 * MY_PI; + aa_theta0_3[i] = theta0_3_one/180.0 * MY_PI; setflag_aa[i] = 1; count++; } @@ -567,7 +566,7 @@ void ImproperClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k0[i] = k0_one; - chi0[i] = chi0_one/180.0 * PI; + chi0[i] = chi0_one/180.0 * MY_PI; setflag_i[i] = 1; count++; } diff --git a/src/CLASS2/improper_class2.h b/src/CLASS2/improper_class2.h index 56c7c9d14a..9a86e9cd86 100644 --- a/src/CLASS2/improper_class2.h +++ b/src/CLASS2/improper_class2.h @@ -38,7 +38,6 @@ class ImproperClass2 : public Improper { double *k0,*chi0; double *aa_k1,*aa_k2,*aa_k3,*aa_theta0_1,*aa_theta0_2,*aa_theta0_3; int *setflag_i,*setflag_aa; - double PI; void allocate(); void angleangle(int, int); diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index aba3715cc1..ee5d7d3e32 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -19,10 +19,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -254,14 +256,13 @@ double PairLJClass2::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index b6dc7d8018..9cd784ff58 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -20,10 +20,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -307,14 +309,13 @@ double PairLJClass2CoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index b9423c4728..34ff47d804 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -22,10 +22,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -321,14 +323,13 @@ double PairLJClass2CoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp index 5eb072b93e..f3c9a0dc06 100644 --- a/src/COLLOID/pair_lubricate.cpp +++ b/src/COLLOID/pair_lubricate.cpp @@ -28,11 +28,13 @@ #include "neigh_list.h" #include "neigh_request.h" #include "update.h" -#include "memory.h" #include "random_mars.h" +#include "math_const.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -73,7 +75,6 @@ void PairLubricate::compute(int eflag, int vflag) double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3; double a_squeeze,a_shear,a_pump,a_twist; int *ilist,*jlist,*numneigh,**firstneigh; - double PI = 4.0*atan(1.0); if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -190,16 +191,16 @@ void PairLubricate::compute(int eflag, int vflag) h_sep = r - 2.0*radi; if (flag1) - a_squeeze = (3.0*PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); if (flag2) - a_shear = (PI*mu*2.*radi/2.0) * + a_shear = (MY_PI*mu*2.*radi/2.0) * log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0; if (flag3) - a_pump = (PI*mu*pow(2.0*radi,4)/8.0) * + a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) * ((3.0/20.0) * log(2.0*radi/2.0/h_sep) + (63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep)); if (flag4) - a_twist = (PI*mu*pow(2.0*radi,4)/4.0) * + a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) * (h_sep/2.0/radi) * log(2.0/(2.0*h_sep)); if (h_sep >= cut_inner[itype][jtype]) { @@ -231,7 +232,7 @@ void PairLubricate::compute(int eflag, int vflag) torque[i][2] += vxmu2f * tz; } else { - a_squeeze = (3.0*PI*mu*2.0*radi/2.0) * + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/cut_inner[itype][jtype]); fpair = -a_squeeze*vnnr; fpair *= vxmu2f; diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp index 044d018c28..0fa91a2518 100644 --- a/src/GPU/pppm_gpu.cpp +++ b/src/GPU/pppm_gpu.cpp @@ -32,11 +32,13 @@ #include "domain.h" #include "fft3d_wrap.h" #include "remap_wrap.h" +#include "gpu_extra.h" +#include "math_const.h" #include "memory.h" #include "error.h" -#include "gpu_extra.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXORDER 7 #define OFFSET 16384 @@ -189,7 +191,7 @@ void PPPMGPU::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp index 4dcf9fc3bc..03a1c3a62a 100644 --- a/src/GRANULAR/fix_pour.cpp +++ b/src/GRANULAR/fix_pour.cpp @@ -27,10 +27,12 @@ #include "region_block.h" #include "region_cylinder.h" #include "random_park.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EPSILON 0.001 @@ -54,8 +56,6 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : if (seed <= 0) error->all(FLERR,"Illegal fix pour command"); - PI = 4.0*atan(1.0); - // option defaults int iregion = -1; @@ -214,11 +214,11 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : double dy = yhi - ylo; if (dy < 1.0) dy = 1.0; volume = (xhi-xlo) * dy * (zhi-zlo); - } else volume = PI*rc*rc * (zhi-zlo); - volume_one = 4.0/3.0 * PI * radius_hi*radius_hi*radius_hi; + } else volume = MY_PI*rc*rc * (zhi-zlo); + volume_one = 4.0/3.0 * MY_PI * radius_hi*radius_hi*radius_hi; } else { volume = (xhi-xlo) * (yhi-ylo); - volume_one = PI * radius_hi*radius_hi; + volume_one = MY_PI * radius_hi*radius_hi; } nper = static_cast (volfrac*volume/volume_one); @@ -472,7 +472,7 @@ void FixPour::pre_exchange() m = atom->nlocal - 1; atom->type[m] = ntype; atom->radius[m] = radtmp; - atom->rmass[m] = 4.0*PI/3.0 * radtmp*radtmp*radtmp * denstmp; + atom->rmass[m] = 4.0*MY_PI/3.0 * radtmp*radtmp*radtmp * denstmp; atom->mask[m] = 1 | groupbit; atom->v[m][0] = vxtmp; atom->v[m][1] = vytmp; diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h index ec9590b276..1880597139 100644 --- a/src/GRANULAR/fix_pour.h +++ b/src/GRANULAR/fix_pour.h @@ -56,7 +56,6 @@ class FixPour : public Fix { int me,nprocs; int *recvcounts,*displs; - double PI; int nfreq,nfirst,ninserted,nper; double lo_current,hi_current; class FixShearHistory *fix_history; diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 0345274cb0..020425d110 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -26,10 +26,12 @@ #include "pair.h" #include "modify.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{XPLANE,YPLANE,ZPLANE,ZCYLINDER}; // XYZ PLANE need to be 0,1,2 enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY}; @@ -159,10 +161,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : // setup oscillations - if (wiggle) { - double PI = 4.0 * atan(1.0); - omega = 2.0*PI / period; - } + if (wiggle) omega = 2.0*MY_PI / period; // perform initial allocation of atom-based arrays // register with Atom class diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp index 5b6d46750a..edd030b55b 100644 --- a/src/KSPACE/ewald.cpp +++ b/src/KSPACE/ewald.cpp @@ -26,10 +26,12 @@ #include "force.h" #include "pair.h" #include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.00001 @@ -40,7 +42,6 @@ Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command"); precision = atof(arg[0]); - PI = 4.0*atan(1.0); kmax = 0; kxvecs = kyvecs = kzvecs = NULL; @@ -165,17 +166,17 @@ void Ewald::setup() double zprd_slab = zprd*slab_volfactor; volume = xprd * yprd * zprd_slab; - unitk[0] = 2.0*PI/xprd; - unitk[1] = 2.0*PI/yprd; - unitk[2] = 2.0*PI/zprd_slab; + unitk[0] = 2.0*MY_PI/xprd; + unitk[1] = 2.0*MY_PI/yprd; + unitk[2] = 2.0*MY_PI/zprd_slab; // determine kmax // function of current box size, precision, G_ewald (short-range cutoff) - int nkxmx = static_cast ((g_ewald*xprd/PI) * sqrt(-log(precision))); - int nkymx = static_cast ((g_ewald*yprd/PI) * sqrt(-log(precision))); + int nkxmx = static_cast ((g_ewald*xprd/MY_PI) * sqrt(-log(precision))); + int nkymx = static_cast ((g_ewald*yprd/MY_PI) * sqrt(-log(precision))); int nkzmx = - static_cast ((g_ewald*zprd_slab/PI) * sqrt(-log(precision))); + static_cast ((g_ewald*zprd_slab/MY_PI) * sqrt(-log(precision))); int kmax_old = kmax; kmax = MAX(nkxmx,nkymx); @@ -281,9 +282,8 @@ void Ewald::compute(int eflag, int vflag) for (k = 0; k < kcount; k++) energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - PI = 4.0*atan(1.0); energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } @@ -495,7 +495,7 @@ void Ewald::coeffs() double unitky = unitk[1]; double unitkz = unitk[2]; double g_ewald_sq_inv = 1.0 / (g_ewald*g_ewald); - double preu = 4.0*PI/volume; + double preu = 4.0*MY_PI/volume; kcount = 0; @@ -817,13 +817,13 @@ void Ewald::slabcorr(int eflag) // compute corrections - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; + double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume; if (eflag) energy += qqrd2e*scale * e_slabcorr; // add on force corrections - double ffact = -4.0*PI*dipole_all/volume; + double ffact = -4.0*MY_PI*dipole_all/volume; double **f = atom->f; for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact; diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h index 250b524de0..95482cfbfe 100644 --- a/src/KSPACE/ewald.h +++ b/src/KSPACE/ewald.h @@ -34,7 +34,6 @@ class Ewald : public KSpace { double memory_usage(); private: - double PI; double precision; int kcount,kmax,kmax3d,kmax_created; double qqrd2e; diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp index dca8532d35..2e607cd74d 100644 --- a/src/KSPACE/pair_born_coul_long.cpp +++ b/src/KSPACE/pair_born_coul_long.cpp @@ -26,10 +26,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -313,7 +315,6 @@ double PairBornCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; @@ -321,11 +322,11 @@ double PairBornCoulLong::init_one(int i, int j) double rc2 = rc*rc; double rc3 = rc2*rc; double rc5 = rc3*rc2; - etail_ij = 2.0*PI*all[0]*all[1] * + etail_ij = 2.0*MY_PI*all[0]*all[1] * (a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1* (rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] * + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] * (-a[i][j]*exp((sigma[i][j]-rc)/rho1) * (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5)); diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp index 813b3b025a..a68029f367 100644 --- a/src/KSPACE/pair_buck_coul_long.cpp +++ b/src/KSPACE/pair_buck_coul_long.cpp @@ -22,10 +22,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -293,17 +295,16 @@ double PairBuckCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut_lj[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp index ba9e390baa..ff8fb1fd22 100644 --- a/src/KSPACE/pair_lj_cut_coul_long.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long.cpp @@ -30,10 +30,12 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -770,15 +772,14 @@ double PairLJCutCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index e8c623b47b..3f0cb6e253 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -29,10 +29,12 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXLINE 1024 #define TOL 1.0e-9 @@ -52,8 +54,6 @@ PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp) maxpage = 0; pages = NULL; nC = nH = NULL; - - PI = 4.0*atan(1.0); } /* ---------------------------------------------------------------------- @@ -1218,8 +1218,8 @@ double PairAIREBO::Sp(double Xij, double Xmin, double Xmax, double &dX) dX = 0.0; } else { - cutoff = 0.5 * (1.0+cos(PI*t)); - dX = (-0.5*PI*sin(PI*t)) / (Xmax-Xmin); + cutoff = 0.5 * (1.0+cos(MY_PI*t)); + dX = (-MY_PI2*sin(MY_PI*t)) / (Xmax-Xmin); } return cutoff; } diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index b51c00bf2b..166e1ed4ed 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -46,7 +46,6 @@ class PairAIREBO : public Pair { int npage; // current page in page list int *map; // 0 (C), 1 (H), or -1 (NULL) for each type - double PI; double cutlj; // user-specified LJ cutoff double cutljrebosq; // cut for when to compute // REBO neighs of ghost atoms diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 5c47b8dcf1..2311ea8d1e 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -29,12 +29,14 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" -#include "memory.h" -#include "error.h" #include "group.h" #include "update.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXLINE 1024 #define DELTA 4 @@ -47,11 +49,6 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp) single_enable = 0; one_coeff = 1; - PI = 4.0*atan(1.0); - PI2 = 2.0*atan(1.0); - PI4 = atan(1.0); - PIsq = sqrt(PI); - nmax = 0; NCo = NULL; bbij = NULL; @@ -930,7 +927,7 @@ double PairComb::elp(Param *param, double rsqij, double rsqik, double rij,rik,costheta,lp1,lp3,lp6; double rmu,rmu2,comtt,fck; double pplp1 = param->plp1, pplp3 = param->plp3, pplp6 = param->plp6; - double c123 = cos(param->a123*PI/180.0); + double c123 = cos(param->a123*MY_PI/180.0); // cos(theta) of the i-j-k // cutoff function of rik @@ -984,7 +981,7 @@ void PairComb::flp(Param *param, double rsqij, double rsqik, double pplp1 = param->plp1; double pplp3 = param->plp3; double pplp6 = param->plp6; - double c123 = cos(param->a123*PI/180.0); + double c123 = cos(param->a123*MY_PI/180.0); // fck_d = derivative of cutoff function @@ -1083,7 +1080,7 @@ double PairComb::comb_fc(double r, Param *param) if (r < comb_R-comb_D) return 1.0; if (r > comb_R+comb_D) return 0.0; - return 0.5*(1.0 + cos(PI*(r - comb_R)/comb_D)); + return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/comb_D)); } /* ---------------------------------------------------------------------- */ @@ -1095,7 +1092,7 @@ double PairComb::comb_fc_d(double r, Param *param) if (r < comb_R-comb_D) return 0.0; if (r > comb_R+comb_D) return 0.0; - return -(PI2/comb_D) * sin(PI*(r - comb_R)/comb_D); + return -(MY_PI2/comb_D) * sin(MY_PI*(r - comb_R)/comb_D); } /* ---------------------------------------------------------------------- */ @@ -1107,7 +1104,7 @@ double PairComb::comb_fc2(double r) if (r < comb_R) return 0.0; if (r > comb_D) return 1.0; - return 0.5*(1.0 + cos(PI*(r - comb_R)/(comb_D-comb_R))); + return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R))); } /* ---------------------------------------------------------------------- */ @@ -1119,7 +1116,7 @@ double PairComb::comb_fc2_d(double r) if (r < comb_R) return 0.0; if (r > comb_D) return 0.0; - return -(PI2/(comb_D-comb_R)) * sin(PI*(r - comb_R)/(comb_D-comb_R)); + return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R)); } /* ---------------------------------------------------------------------- */ @@ -1131,7 +1128,7 @@ double PairComb::comb_fc3(double r) if (r < comb_R) return 1.0; if (r > comb_D) return 0.0; - return 0.5*(1.0 + cos(PI*(r - comb_R)/(comb_D-comb_R))); + return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R))); } /* ---------------------------------------------------------------------- */ @@ -1143,7 +1140,7 @@ double PairComb::comb_fc3_d(double r) if (r < comb_R) return 0.0; if (r > comb_D) return 0.0; - return -(PI2/(comb_D-comb_R)) * sin(PI*(r - comb_R)/(comb_D-comb_R)); + return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R)); } /* ---------------------------------------------------------------------- */ @@ -1541,10 +1538,10 @@ void PairComb::potal_calc(double &calc1, double &calc2, double &calc3) alf = 0.20; esucon = force->qqr2e; - calc2 = (erfc(rcoul*alf)/rcoul/rcoul+2.0*alf/PIsq* + calc2 = (erfc(rcoul*alf)/rcoul/rcoul+2.0*alf/MY_PIS* exp(-alf*alf*rcoul*rcoul)/rcoul)*esucon/rcoul; calc3 = (erfc(rcoul*alf)/rcoul)*esucon; - calc1 = -(alf/PIsq*esucon+calc3*0.5); + calc1 = -(alf/MY_PIS*esucon+calc3*0.5); } /* ---------------------------------------------------------------------- */ @@ -1590,7 +1587,7 @@ void PairComb::direct(int inty, int mr1, int mr2, int mr3, double rsq, r = sqrt(rsq); r3 = r * rsq; alf = 0.20; - alfdpi = 2.0*alf/PIsq; + alfdpi = 2.0*alf/MY_PIS; esucon = force->qqr2e; pot_tmp = 0.0; pot_d = 0.0; diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h index c8782b4bbf..bda2805d56 100644 --- a/src/MANYBODY/pair_comb.h +++ b/src/MANYBODY/pair_comb.h @@ -58,7 +58,6 @@ class PairComb : public Pair { int powermint; }; - double PI,PI2,PI4,PIsq; double cutmax; // max cutoff for all elements int nelements; // # of unique elements char **elements; // names of unique elements diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index 9016a26b28..9c8654100d 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -30,10 +30,12 @@ #include "random_park.h" #include "force.h" #include "pair.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -71,10 +73,9 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : // compute beta, lambda, sigma, and the zz factor beta = 1.0/(force->boltz*reservoir_temperature); - double PI = 4.0*atan(1.0); double gas_mass = atom->mass[ntype]; double lambda = sqrt(force->hplanck*force->hplanck/ - (2.0*PI*gas_mass*force->mvv2e* + (2.0*MY_PI*gas_mass*force->mvv2e* force->boltz*reservoir_temperature)); sigma = sqrt(force->boltz*reservoir_temperature/gas_mass/force->mvv2e); zz = exp(beta*chemical_potential)/(pow(lambda,3)); diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp index 5dd81580cc..0361209e66 100644 --- a/src/MOLECULE/angle_charmm.cpp +++ b/src/MOLECULE/angle_charmm.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -209,7 +211,7 @@ void AngleCharmm::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; k_ub[i] = k_ub_one; r_ub[i] = r_ub_one; setflag[i] = 1; diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp index 6c6fa4fc87..dc82378083 100644 --- a/src/MOLECULE/angle_cosine.cpp +++ b/src/MOLECULE/angle_cosine.cpp @@ -19,10 +19,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -174,7 +176,7 @@ void AngleCosine::coeff(int narg, char **arg) double AngleCosine::equilibrium_angle(int i) { - return PI; + return MY_PI; } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp index d401c1fffc..8aaf54cb9f 100644 --- a/src/MOLECULE/angle_cosine_periodic.cpp +++ b/src/MOLECULE/angle_cosine_periodic.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -226,7 +228,7 @@ void AngleCosinePeriodic::coeff(int narg, char **arg) double AngleCosinePeriodic::equilibrium_angle(int i) { - return PI; + return MY_PI; } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp index 9262700679..95c1a3b922 100644 --- a/src/MOLECULE/angle_cosine_squared.cpp +++ b/src/MOLECULE/angle_cosine_squared.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -178,7 +180,7 @@ void AngleCosineSquared::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp index e3def97499..8a462abaed 100644 --- a/src/MOLECULE/angle_harmonic.cpp +++ b/src/MOLECULE/angle_harmonic.cpp @@ -19,10 +19,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -178,7 +180,7 @@ void AngleHarmonic::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp index 4395c20413..a8e6254500 100644 --- a/src/MOLECULE/angle_table.cpp +++ b/src/MOLECULE/angle_table.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{LINEAR,SPLINE}; @@ -238,8 +240,8 @@ void AngleTable::coeff(int narg, char **arg) // convert theta from degrees to radians for (int i = 0; i < tb->ninput; i++){ - tb->afile[i] *= PI/180.0; - tb->ffile[i] *= 180.0/PI; + tb->afile[i] *= MY_PI/180.0; + tb->ffile[i] *= 180.0/MY_PI; } // spline read-in and compute a,e,f vectors within table @@ -442,7 +444,7 @@ void AngleTable::compute_table(Table *tb) // delta = table spacing in angle for N-1 bins int tlm1 = tablength-1; - tb->delta = PI/ tlm1; + tb->delta = MY_PI / tlm1; tb->invdelta = 1.0/tb->delta; tb->deltasq6 = tb->delta*tb->delta / 6.0; @@ -501,8 +503,8 @@ void AngleTable::param_extract(Table *tb, char *line) tb->fplo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->fphi = atof(word); - tb->fplo *= (180.0/PI)*(180.0/PI); - tb->fphi *= (180.0/PI)*(180.0/PI); + tb->fplo *= (180.0/MY_PI)*(180.0/MY_PI); + tb->fphi *= (180.0/MY_PI)*(180.0/MY_PI); } else if (strcmp(word,"EQ") == 0) { word = strtok(NULL," \t\n\r\f"); tb->theta0 = atof(word); diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index a404311150..c762a56ad5 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -27,10 +27,12 @@ #include "force.h" #include "pair.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 @@ -344,14 +346,12 @@ void DihedralCharmm::coeff(int narg, char **arg) if (weight_one < 0.0 || weight_one > 1.0) error->all(FLERR,"Incorrect weight arg for dihedral coefficients"); - double PI = 4.0*atan(1.0); - int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; shift[i] = shift_one; - cos_shift[i] = cos(PI*shift_one/180.0); - sin_shift[i] = sin(PI*shift_one/180.0); + cos_shift[i] = cos(MY_PI*shift_one/180.0); + sin_shift[i] = sin(MY_PI*shift_one/180.0); multiplicity[i] = multiplicity_one; weight[i] = weight_one; setflag[i] = 1; @@ -420,10 +420,9 @@ void DihedralCharmm::read_restart(FILE *fp) MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - double PI = 4.0*atan(1.0); for (int i = 1; i <= atom->ndihedraltypes; i++) { setflag[i] = 1; - cos_shift[i] = cos(PI*shift[i]/180.0); - sin_shift[i] = sin(PI*shift[i]/180.0); + cos_shift[i] = cos(MY_PI*shift[i]/180.0); + sin_shift[i] = sin(MY_PI*shift[i]/180.0); } } diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp index 7a50eb4fc0..ee93d2a08d 100644 --- a/src/MOLECULE/dihedral_helix.cpp +++ b/src/MOLECULE/dihedral_helix.cpp @@ -27,10 +27,12 @@ #include "comm.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -192,9 +194,9 @@ void DihedralHelix::compute(int eflag, int vflag) siinv = 1.0/si; p = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + - cphi[type]*(1.0 + cos(phi + 0.25*PI)); + cphi[type]*(1.0 + cos(phi + MY_PI4)); pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + - cphi[type]*sin(phi + 0.25*PI)*siinv; + cphi[type]*sin(phi + MY_PI4)*siinv; if (eflag) edihedral = p; diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp index 62d5cd54b6..87d94079bd 100644 --- a/src/MOLECULE/improper_harmonic.cpp +++ b/src/MOLECULE/improper_harmonic.cpp @@ -22,10 +22,12 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -248,7 +250,7 @@ void ImproperHarmonic::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - chi[i] = chi_one/180.0 * PI; + chi[i] = chi_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp index 34fddf708a..97a127b318 100644 --- a/src/MOLECULE/improper_umbrella.cpp +++ b/src/MOLECULE/improper_umbrella.cpp @@ -25,10 +25,12 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -269,7 +271,7 @@ void ImproperUmbrella::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { kw[i] = k_one; - w0[i] = w_one/180.0 * PI; + w0[i] = w_one/180.0 * MY_PI; if (w_one == 0) C[i] = 1.0; else C[i] = kw[i]/(pow(sin(w0[i]),2)); setflag[i] = 1; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index eae9e4aa83..104cf83e6d 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -26,11 +26,13 @@ #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" +#include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" -#include "domain.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 #define CHUNK 8 @@ -44,8 +46,6 @@ PairHbondDreidingLJ::PairHbondDreidingLJ(LAMMPS *lmp) : Pair(lmp) no_virial_fdotr_compute = 1; - PI = 4.0*atan(1.0); - nparams = maxparam = 0; params = NULL; @@ -159,7 +159,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (c < -1.0) c = -1.0; ac = acos(c); - if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) { + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; @@ -279,7 +279,7 @@ void PairHbondDreidingLJ::settings(int narg, char **arg) ap_global = force->inumeric(arg[0]); cut_inner_global = force->numeric(arg[1]); cut_outer_global = force->numeric(arg[2]); - cut_angle_global = force->numeric(arg[3]) * PI/180.0; + cut_angle_global = force->numeric(arg[3]) * MY_PI/180.0; } /* ---------------------------------------------------------------------- @@ -316,7 +316,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg) if (cut_inner_one>cut_outer_one) error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; - if (narg == 10) cut_angle_one = force->numeric(arg[9]) * PI/180.0; + if (narg == 10) cut_angle_one = force->numeric(arg[9]) * MY_PI/180.0; // grow params array if necessary if (nparams == maxparam) { @@ -500,7 +500,7 @@ double PairHbondDreidingLJ::single(int i, int j, int itype, int jtype, if (c < -1.0) c = -1.0; ac = acos(c); - if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0; + if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0; s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.h b/src/MOLECULE/pair_hbond_dreiding_lj.h index 387cd3f095..1304743b8d 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.h +++ b/src/MOLECULE/pair_hbond_dreiding_lj.h @@ -38,7 +38,6 @@ class PairHbondDreidingLJ : public Pair { protected: double cut_inner_global,cut_outer_global,cut_angle_global; int ap_global; - double PI; struct Param { double epsilon,sigma; diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp index ebd3b27ef0..e7f9c1e7c5 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp @@ -26,11 +26,13 @@ #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" +#include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" -#include "domain.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 #define CHUNK 8 @@ -128,7 +130,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (c < -1.0) c = -1.0; ac = acos(c); - if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) { + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; @@ -242,7 +244,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg) if (cut_inner_one>cut_outer_one) error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; - if (narg > 10) cut_angle_one = force->numeric(arg[10]) * PI/180.0; + if (narg > 10) cut_angle_one = force->numeric(arg[10]) * MY_PI/180.0; // grow params array if necessary @@ -404,7 +406,7 @@ double PairHbondDreidingMorse::single(int i, int j, int itype, int jtype, if (c < -1.0) c = -1.0; ac = acos(c); - if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0; + if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0; s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index ec0d07d20d..411beb9c9d 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -34,10 +34,12 @@ #include "fix_wall_srd.h" #include "random_mars.h" #include "random_park.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{SLIP,NOSLIP}; enum{SPHERE,ELLIPSOID,WALL}; @@ -2087,8 +2089,6 @@ int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew, void FixSRD::parameterize() { - double PI = 4.0*atan(1.0); - // timesteps dt_big = update->dt; @@ -2194,20 +2194,20 @@ void FixSRD::parameterize() for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { if (radius && radius[i] > 0.0) - volbig += 4.0/3.0*PI*radius[i]*radius[i]*radius[i]; + volbig += 4.0/3.0*MY_PI*radius[i]*radius[i]*radius[i]; else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += 4.0/3.0*PI * shape[0]*shape[1]*shape[2]; + volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2]; } } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { if (radius && radius[i] > 0.0) - volbig += PI*radius[i]*radius[i]; + volbig += MY_PI*radius[i]*radius[i]; else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += PI*shape[0]*shape[1]; + volbig += MY_PI*shape[0]*shape[1]; } } } diff --git a/src/USER-CG-CMM/angle_cg_cmm.cpp b/src/USER-CG-CMM/angle_cg_cmm.cpp index 7d9800808a..070d65c5b8 100644 --- a/src/USER-CG-CMM/angle_cg_cmm.cpp +++ b/src/USER-CG-CMM/angle_cg_cmm.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -323,7 +325,7 @@ void AngleCGCMM::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k[i] = k_one; // convert theta0 from degrees to radians - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; epsilon[i] = epsilon_one; sigma[i] = sigma_one; rcut[i] = rcut_one; diff --git a/src/USER-CG-CMM/pair_cmm_common.cpp b/src/USER-CG-CMM/pair_cmm_common.cpp index 81d142f568..4e1606d587 100644 --- a/src/USER-CG-CMM/pair_cmm_common.cpp +++ b/src/USER-CG-CMM/pair_cmm_common.cpp @@ -23,8 +23,10 @@ #include "string.h" #include "ctype.h" #include "math.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 1.0e-6 @@ -302,15 +304,14 @@ double PairCMMCommon::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); #endif } diff --git a/src/USER-CUDA/fix_gravity_cuda.cpp b/src/USER-CUDA/fix_gravity_cuda.cpp index 8c6d8488c8..36d7022fa3 100644 --- a/src/USER-CUDA/fix_gravity_cuda.cpp +++ b/src/USER-CUDA/fix_gravity_cuda.cpp @@ -30,12 +30,13 @@ #include "update.h" #include "domain.h" #include "respa.h" -#include "error.h" #include "cuda.h" #include "cuda_modify_flags.h" - +#include "math_const.h" +#include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; @@ -79,8 +80,7 @@ FixGravityCuda::FixGravityCuda(LAMMPS *lmp, int narg, char **arg) : zdir = atof(arg[7]); } else error->all(FLERR,"Illegal fix gravity command"); - double PI = 4.0*atan(1.0); - degree2rad = PI/180.0; + degree2rad = MY_PI/180.0; if (style == CHUTE || style == SPHERICAL || style == GRADIENT) { if (domain->dimension == 3) { diff --git a/src/USER-CUDA/fix_shake_cuda.cpp b/src/USER-CUDA/fix_shake_cuda.cpp index 219ac679bd..cbcb9acaef 100644 --- a/src/USER-CUDA/fix_shake_cuda.cpp +++ b/src/USER-CUDA/fix_shake_cuda.cpp @@ -34,8 +34,10 @@ #include "error.h" #include "cuda.h" #include "cuda_modify_flags.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1.0e20 #define MASSDELTA 0.1 @@ -53,7 +55,6 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); neighbor_step=true; - PI = 4.0*atan(1.0); virial_flag = 1; create_attribute = 1; @@ -2183,7 +2184,7 @@ void FixShakeCuda::stats() r3 = sqrt(delx*delx + dely*dely + delz*delz); angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2)); - angle *= 180.0/PI; + angle *= 180.0/MY_PI; m = shake_type[i][2]; a_count[m]++; a_ave[m] += angle; diff --git a/src/USER-CUDA/fix_shake_cuda.h b/src/USER-CUDA/fix_shake_cuda.h index 18ea64f983..b0ebe584d7 100644 --- a/src/USER-CUDA/fix_shake_cuda.h +++ b/src/USER-CUDA/fix_shake_cuda.h @@ -53,7 +53,6 @@ class FixShakeCuda : public Fix { private: class Cuda *cuda; int me,nprocs; - double PI; double tolerance; // SHAKE tolerance int max_iter; // max # of SHAKE iterations int output_every; // SHAKE stat output every so often diff --git a/src/USER-CUDA/pppm_cuda.cpp b/src/USER-CUDA/pppm_cuda.cpp index 8167eb1d72..5fd8406fbe 100644 --- a/src/USER-CUDA/pppm_cuda.cpp +++ b/src/USER-CUDA/pppm_cuda.cpp @@ -61,8 +61,10 @@ #include "cuda_wrapper_cu.h" #include "pppm_cuda_cu.h" #include "cuda.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXORDER 7 #define OFFSET 4096 @@ -109,7 +111,6 @@ PPPMCuda::PPPMCuda(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, (narg==2?1:nar if(narg>1) precisionmodify=arg[1][0]; else precisionmodify='='; - PI = 4.0*atan(1.0); nfactors = 3; factors = new int[nfactors]; @@ -648,9 +649,9 @@ void PPPMCuda::setup() delvolinv = delxinv*delyinv*delzinv; - double unitkx = (2.0*PI/xprd); - double unitky = (2.0*PI/yprd); - double unitkz = (2.0*PI/zprd_slab); + double unitkx = (2.0*MY_PI/xprd); + double unitky = (2.0*MY_PI/yprd); + double unitkz = (2.0*MY_PI/zprd_slab); // fkx,fky,fkz for my FFT grid pts Cuda_PPPM_Setup_fkxyz_vg(nx_pppm, ny_pppm,nz_pppm,unitkx,unitky,unitkz,g_ewald); @@ -747,11 +748,11 @@ double sqk; double sum1,dot1,dot2; double numerator,denominator; - int nbx = static_cast ((g_ewald*xprd/(PI*nx_pppm)) * + int nbx = static_cast ((g_ewald*xprd/(MY_PI*nx_pppm)) * pow(-log(EPS_HOC),0.25)); - int nby = static_cast ((g_ewald*yprd/(PI*ny_pppm)) * + int nby = static_cast ((g_ewald*yprd/(MY_PI*ny_pppm)) * pow(-log(EPS_HOC),0.25)); - int nbz = static_cast ((g_ewald*zprd_slab/(PI*nz_pppm)) * + int nbz = static_cast ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) * pow(-log(EPS_HOC),0.25)); Cuda_PPPM_setup_greensfn(nx_pppm,ny_pppm,nz_pppm,unitkx,unitky,unitkz,g_ewald, nbx,nby,nbz,xprd,yprd,zprd_slab); @@ -967,7 +968,7 @@ else energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e; } @@ -1728,11 +1729,11 @@ void PPPMCuda::slabcorr(int eflag) // compute corrections - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; + double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume; if (eflag) energy += qqrd2e*scale * e_slabcorr; - double ffact = -4.0*PI*dipole_all/volume; + double ffact = -4.0*MY_PI*dipole_all/volume; cuda_slabcorr_force(&cuda->shared_data,ffact); } diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h index b9372f62a6..6c527cacdd 100644 --- a/src/USER-EFF/atom_vec_electron.h +++ b/src/USER-EFF/atom_vec_electron.h @@ -60,7 +60,6 @@ class AtomVecElectron : public AtomVec { bigint memory_usage(); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; int *spin; diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp index a3ca969ef3..4ec701a0cb 100644 --- a/src/USER-OMP/dihedral_helix_omp.cpp +++ b/src/USER-OMP/dihedral_helix_omp.cpp @@ -25,9 +25,11 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -211,10 +213,10 @@ void DihedralHelixOMP::eval(double **f, int nfrom, int nto, int tid) siinv = 1.0/si; pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + - cphi[type]*sin(phi + 0.25*PI)*siinv; + cphi[type]*sin(phi + MY_PI4)*siinv; if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + - cphi[type]*(1.0 + cos(phi + 0.25*PI)); + cphi[type]*(1.0 + cos(phi + MY_PI4)); ; a = pd; diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp index 7667efa983..9f9673a28b 100644 --- a/src/USER-OMP/pair_soft_omp.cpp +++ b/src/USER-OMP/pair_soft_omp.cpp @@ -19,8 +19,10 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 1.0e-4 @@ -122,7 +124,7 @@ void PairSoftOMP::eval(double **f, int iifrom, int iito, int tid) if (rsq < cutsq[itype][jtype]) { r = sqrt(rsq); - arg = PI/cut[itype][jtype]; + arg = MY_PI/cut[itype][jtype]; if (r > SMALL) fpair = factor_lj * prefactor[itype][jtype] * sin(arg*r) * arg/r; else fpair = 0.0; diff --git a/src/angle.cpp b/src/angle.cpp index fbed9116a9..58ba679948 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -15,10 +15,12 @@ #include "angle.h" #include "atom.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -27,8 +29,6 @@ Angle::Angle(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); - THIRD = 1.0/3.0; maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/angle.h b/src/angle.h index 99d8dc105f..7f25f38289 100644 --- a/src/angle.h +++ b/src/angle.h @@ -40,8 +40,6 @@ class Angle : protected Pointers { virtual double memory_usage(); protected: - double PI,THIRD; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index 47c9ef97f6..4baff5b602 100755 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -25,10 +25,12 @@ #include "domain.h" #include "modify.h" #include "fix.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 #define DELTA_BONUS 10000 @@ -53,8 +55,6 @@ AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) : atom->ellipsoid_flag = 1; atom->rmass_flag = atom->angmom_flag = atom->torque_flag = 1; - PI = 4.0*atan(1.0); - nlocal_bonus = nghost_bonus = nmax_bonus = 0; bonus = NULL; } @@ -1200,7 +1200,7 @@ void AtomVecEllipsoid::data_atom_bonus(int m, char **values) // reset ellipsoid mass // previously stored density in rmass - rmass[m] *= 4.0*PI/3.0 * shape[0]*shape[1]*shape[2]; + rmass[m] *= 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2]; bonus[nlocal_bonus].ilocal = m; ellipsoid[m] = nlocal_bonus++; diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h index 537f1eaab7..0020eb5f28 100755 --- a/src/atom_vec_ellipsoid.h +++ b/src/atom_vec_ellipsoid.h @@ -76,7 +76,6 @@ class AtomVecEllipsoid : public AtomVec { void set_shape(int, double, double, double); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; double *rmass; diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index a3e2c34772..96b2d766d8 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -23,10 +23,12 @@ #include "force.h" #include "fix.h" #include "fix_adapt.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -50,8 +52,6 @@ AtomVecSphere::AtomVecSphere(LAMMPS *lmp, int narg, char **arg) : atom->sphere_flag = 1; atom->radius_flag = atom->rmass_flag = atom->omega_flag = atom->torque_flag = 1; - - PI = 4.0*atan(1.0); } /* ---------------------------------------------------------------------- */ @@ -929,7 +929,7 @@ void AtomVecSphere::create_atom(int itype, double *coord) v[nlocal][2] = 0.0; radius[nlocal] = 0.5; - rmass[nlocal] = 4.0*PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal]; + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal]; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[nlocal][2] = 0.0; @@ -965,7 +965,7 @@ void AtomVecSphere::data_atom(double *coord, int imagetmp, char **values) if (radius[nlocal] == 0.0) rmass[nlocal] = density; else - rmass[nlocal] = 4.0*PI/3.0 * + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; x[nlocal][0] = coord[0]; @@ -1002,7 +1002,7 @@ int AtomVecSphere::data_atom_hybrid(int nlocal, char **values) if (radius[nlocal] == 0.0) rmass[nlocal] = density; else - rmass[nlocal] = 4.0*PI/3.0 * + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; return 2; diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h index 8157029615..78357b7d1a 100644 --- a/src/atom_vec_sphere.h +++ b/src/atom_vec_sphere.h @@ -61,7 +61,6 @@ class AtomVecSphere : public AtomVec { bigint memory_usage(); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; double *radius,*density,*rmass; diff --git a/src/compute_angle_local.cpp b/src/compute_angle_local.cpp index a126348d31..d19b7e71aa 100644 --- a/src/compute_angle_local.cpp +++ b/src/compute_angle_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "angle.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -133,7 +135,6 @@ int ComputeAngleLocal::compute_angles(int flag) } Angle *angle = force->angle; - double PI = 4.0*atan(1.0); m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { @@ -170,7 +171,7 @@ int ComputeAngleLocal::compute_angles(int flag) c /= r1*r2; if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - tbuf[n] = 180.0*acos(c)/PI; + tbuf[n] = 180.0*acos(c)/MY_PI; } if (eflag >= 0) { diff --git a/src/compute_dihedral_local.cpp b/src/compute_dihedral_local.cpp index 6215346717..10cac6f607 100644 --- a/src/compute_dihedral_local.cpp +++ b/src/compute_dihedral_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "dihedral.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 #define SMALL 0.001 @@ -128,8 +130,6 @@ int ComputeDihedralLocal::compute_dihedrals(int flag) } } - double PI = 4.0*atan(1.0); - m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; @@ -190,7 +190,7 @@ int ComputeDihedralLocal::compute_dihedrals(int flag) if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - pbuf[n] = 180.0*atan2(s,c)/PI; + pbuf[n] = 180.0*atan2(s,c)/MY_PI; } n += nvalues; } diff --git a/src/compute_improper_local.cpp b/src/compute_improper_local.cpp index 7162277c39..3285f2561c 100644 --- a/src/compute_improper_local.cpp +++ b/src/compute_improper_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "improper.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -129,8 +131,6 @@ int ComputeImproperLocal::compute_impropers(int flag) } } - double PI = 4.0*atan(1.0); - m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; @@ -188,7 +188,7 @@ int ComputeImproperLocal::compute_impropers(int flag) if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - cbuf[n] = 180.0*acos(c)/PI; + cbuf[n] = 180.0*acos(c)/MY_PI; } n += nvalues; } diff --git a/src/compute_rdf.cpp b/src/compute_rdf.cpp index 9dbe3aded0..31776f9473 100644 --- a/src/compute_rdf.cpp +++ b/src/compute_rdf.cpp @@ -28,10 +28,12 @@ #include "neigh_request.h" #include "neigh_list.h" #include "group.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -267,10 +269,9 @@ void ComputeRDF::compute_array() // assuming J atoms are at uniform density double constant,nideal,gr,ncoord,rlower,rupper; - double PI = 4.0*atan(1.0); if (domain->dimension == 3) { - constant = 4.0*PI / (3.0*domain->xprd*domain->yprd*domain->zprd); + constant = 4.0*MY_PI / (3.0*domain->xprd*domain->yprd*domain->zprd); for (m = 0; m < npairs; m++) { ncoord = 0.0; @@ -289,7 +290,7 @@ void ComputeRDF::compute_array() } } else { - constant = PI / (domain->xprd*domain->yprd); + constant = MY_PI / (domain->xprd*domain->yprd); for (m = 0; m < npairs; m++) { ncoord = 0.0; diff --git a/src/dihedral.cpp b/src/dihedral.cpp index a3edadc0c0..974df81b14 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -32,7 +32,6 @@ Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/dihedral.h b/src/dihedral.h index c41cedad03..b41272b7ba 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -41,8 +41,6 @@ class Dihedral : protected Pointers { virtual double memory_usage(); protected: - double PI; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/dump_image.cpp b/src/dump_image.cpp index 25dc36109f..16f677327e 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -30,6 +30,7 @@ #include "input.h" #include "variable.h" #include "random_mars.h" +#include "math_const.h" #include "error.h" #include "memory.h" @@ -38,6 +39,7 @@ #endif using namespace LAMMPS_NS; +using namespace MathConst; #define NCOLORS 140 #define NELEMENTS 109 @@ -57,8 +59,6 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : { if (binary || multiproc) error->all(FLERR,"Invalid dump image filename"); - PI = 4.0*atan(1.0); - // set filetype based on filename suffix int n = strlen(filename); @@ -95,8 +95,8 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : bdiamvalue = 0.5; } width = height = 512; - theta = 60.0 * PI/180.0; - phi = 30.0 * PI/180.0; + theta = 60.0 * MY_PI/180.0; + phi = 30.0 * MY_PI/180.0; thetastr = phistr = NULL; cflag = STATIC; cx = cy = cz = 0.5; @@ -171,7 +171,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : theta = atof(arg[iarg+1]); if (theta < 0.0 || theta > 180.0) error->all(FLERR,"Invalid dump image theta value"); - theta *= PI/180.0; + theta *= MY_PI/180.0; } if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; @@ -179,7 +179,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : strcpy(phistr,&arg[iarg+2][2]); } else { phi = atof(arg[iarg+2]); - phi *= PI/180.0; + phi *= MY_PI/180.0; } iarg += 3; @@ -358,25 +358,25 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : // static parameters - FOV = PI/6.0; // 30 degrees + FOV = MY_PI/6.0; // 30 degrees ambientColor[0] = 0.0; ambientColor[1] = 0.0; ambientColor[2] = 0.0; - keyLightPhi = -PI/4.0; // -45 degrees - keyLightTheta = PI/6.0; // 30 degrees + keyLightPhi = -MY_PI4; // -45 degrees + keyLightTheta = MY_PI/6.0; // 30 degrees keyLightColor[0] = 0.9; keyLightColor[1] = 0.9; keyLightColor[2] = 0.9; - fillLightPhi = PI/6.0; // 30 degrees + fillLightPhi = MY_PI/6.0; // 30 degrees fillLightTheta = 0; fillLightColor[0] = 0.45; fillLightColor[1] = 0.45; fillLightColor[2] = 0.45; - backLightPhi = PI; // 180 degrees - backLightTheta = PI/12.0; // 15 degrees + backLightPhi = MY_PI; // 180 degrees + backLightTheta = MY_PI/12.0; // 15 degrees backLightColor[0] = 0.9; backLightColor[1] = 0.9; backLightColor[2] = 0.9; @@ -676,11 +676,11 @@ void DumpImage::view_params() theta = input->variable->compute_equal(thetavar); if (theta < 0.0 || theta > 180.0) error->all(FLERR,"Invalid dump image theta value"); - theta *= PI/180.0; + theta *= MY_PI/180.0; } if (phistr) { phi = input->variable->compute_equal(phivar); - phi *= PI/180.0; + phi *= MY_PI/180.0; } camDir[0] = sin(theta)*cos(phi); @@ -764,7 +764,7 @@ void DumpImage::view_params() if (ssao) { SSAORadius = maxdel * 0.05 * ssaoint; SSAOSamples = static_cast (8.0 + 32.0*ssaoint); - SSAOJitter = PI / 12; + SSAOJitter = MY_PI / 12; ambientColor[0] = 0.5; ambientColor[1] = 0.5; ambientColor[2] = 0.5; @@ -1358,7 +1358,7 @@ void DumpImage::compute_SSAO() { // used for rasterizing the spheres - double delTheta = 2.0*PI / SSAOSamples; + double delTheta = 2.0*MY_PI / SSAOSamples; // typical neighborhood value for shading diff --git a/src/dump_image.h b/src/dump_image.h index 866fc32e89..844ba1c112 100644 --- a/src/dump_image.h +++ b/src/dump_image.h @@ -69,8 +69,6 @@ class DumpImage : public DumpCustom { // constant view params - double PI; - double FOV; double ambientColor[3]; diff --git a/src/fix_adapt.cpp b/src/fix_adapt.cpp index fd1a256b8a..59af597bc3 100644 --- a/src/fix_adapt.cpp +++ b/src/fix_adapt.cpp @@ -24,10 +24,12 @@ #include "kspace.h" #include "input.h" #include "variable.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{PAIR,KSPACE,ATOM}; enum{DIAMETER}; @@ -309,7 +311,6 @@ void FixAdapt::change_settings() if (ad->aparam == DIAMETER) { int mflag = 0; if (atom->rmass_flag) mflag = 1; - double PI = 4.0*atan(1.0); double density; double *radius = atom->radius; @@ -324,9 +325,11 @@ void FixAdapt::change_settings() } else { for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { - density = rmass[i] / (4.0*PI/3.0 * radius[i]*radius[i]*radius[i]); + density = rmass[i] / (4.0*MY_PI/3.0 * + radius[i]*radius[i]*radius[i]); radius[i] = 0.5*value; - rmass[i] = 4.0*PI/3.0 * radius[i]*radius[i]*radius[i] * density; + rmass[i] = 4.0*MY_PI/3.0 * + radius[i]*radius[i]*radius[i] * density; } } } diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index 039bba40b2..097683ad23 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -27,10 +27,12 @@ #include "lattice.h" #include "force.h" #include "modify.h" +#include "math_const.h" #include "kspace.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE}; enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE}; @@ -305,7 +307,7 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (force_reneighbor) irregular = new Irregular(lmp); else irregular = NULL; - TWOPI = 8.0*atan(1.0); + TWOPI = 2.0*MY_PI; } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_gravity.cpp b/src/fix_gravity.cpp index 09a2e2c7f1..de71e6bd79 100644 --- a/src/fix_gravity.cpp +++ b/src/fix_gravity.cpp @@ -20,9 +20,11 @@ #include "update.h" #include "domain.h" #include "respa.h" +#include "math_const.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; @@ -65,8 +67,7 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) : zdir = atof(arg[7]); } else error->all(FLERR,"Illegal fix gravity command"); - double PI = 4.0*atan(1.0); - degree2rad = PI/180.0; + degree2rad = MY_PI/180.0; if (style == CHUTE || style == SPHERICAL || style == GRADIENT) { if (domain->dimension == 3) { diff --git a/src/fix_move.cpp b/src/fix_move.cpp index afd087772e..74657fa86e 100644 --- a/src/fix_move.cpp +++ b/src/fix_move.cpp @@ -26,10 +26,12 @@ #include "respa.h" #include "input.h" #include "variable.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{LINEAR,WIGGLE,ROTATE,VARIABLE}; enum{EQUAL,ATOM}; @@ -216,10 +218,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : // set omega_rotate from period - if (mstyle == WIGGLE || mstyle == ROTATE) { - double PI = 4.0 * atan(1.0); - omega_rotate = 2.0*PI / period; - } + if (mstyle == WIGGLE || mstyle == ROTATE) omega_rotate = 2.0*MY_PI / period; // runit = unit vector along rotation axis diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp index d0269acddb..109373add7 100644 --- a/src/fix_orient_fcc.cpp +++ b/src/fix_orient_fcc.cpp @@ -28,10 +28,12 @@ #include "neigh_request.h" #include "comm.h" #include "output.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1000000000 @@ -77,7 +79,6 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : // initializations - PI = 4.0*atan(1.0); half_fcc_nn = 6; use_xismooth = false; double xicutoff = 1.57; @@ -344,10 +345,10 @@ void FixOrientFCC::post_force(int vflag) edelta = Vxi; order[i][1] = 1.0; } else { - omega = (0.5*PI)*(xi_total-xi0) / (xi1-xi0); - nbr[i].duxi = PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0)); + omega = MY_PI2*(xi_total-xi0) / (xi1-xi0); + nbr[i].duxi = MY_PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0)); edelta = Vxi*(1 - cos(2.0*omega)) / 2.0; - order[i][1] = omega / (0.5*PI); + order[i][1] = omega / MY_PI2; } added_energy += edelta; } diff --git a/src/fix_orient_fcc.h b/src/fix_orient_fcc.h index f401d30855..b83753619b 100644 --- a/src/fix_orient_fcc.h +++ b/src/fix_orient_fcc.h @@ -58,7 +58,6 @@ class FixOrientFCC : public Fix { private: int me; - double PI; int nlevels_respa; int direction_of_motion; // 1 = center shrinks, 0 = center grows diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp index 43f7f61087..f3048cc18d 100644 --- a/src/fix_restrain.cpp +++ b/src/fix_restrain.cpp @@ -26,10 +26,12 @@ #include "comm.h" #include "respa.h" #include "input.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{DIHEDRAL}; @@ -83,13 +85,12 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : // special treatment for dihedral restraints if (rstyle == DIHEDRAL) { - double PI = 4.0*atan(1.0); cos_shift = (double *) memory->smalloc(n_bonds * sizeof(double), "restrain:cos_shift"); sin_shift = (double *) memory->smalloc(n_bonds * sizeof(double), "restrain:sin_shift"); for (ibond = 0; ibond < n_bonds; ibond++) { - double my_arg = PI * (180.0 + target[ibond]) / 180.0; + double my_arg = MY_PI * (180.0 + target[ibond]) / 180.0; cos_shift[ibond] = cos(my_arg); sin_shift[ibond] = sin(my_arg); } diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp index e00e84e424..5cdce3ad25 100644 --- a/src/fix_shake.cpp +++ b/src/fix_shake.cpp @@ -30,10 +30,12 @@ #include "comm.h" #include "group.h" #include "fix_respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1.0e20 #define MASSDELTA 0.1 @@ -46,8 +48,6 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); - PI = 4.0*atan(1.0); - virial_flag = 1; create_attribute = 1; @@ -2114,7 +2114,7 @@ void FixShake::stats() r3 = sqrt(delx*delx + dely*dely + delz*delz); angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2)); - angle *= 180.0/PI; + angle *= 180.0/MY_PI; m = shake_type[i][2]; a_count[m]++; a_ave[m] += angle; diff --git a/src/fix_shake.h b/src/fix_shake.h index eaf39837cb..b0aa5c63d2 100644 --- a/src/fix_shake.h +++ b/src/fix_shake.h @@ -49,7 +49,6 @@ class FixShake : public Fix { private: int me,nprocs; - double PI; double tolerance; // SHAKE tolerance int max_iter; // max # of SHAKE iterations int output_every; // SHAKE stat output every so often diff --git a/src/improper.cpp b/src/improper.cpp index 3c65e8c89c..8f5ab4d6e3 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -27,7 +27,6 @@ Improper::Improper(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/improper.h b/src/improper.h index 711f124c20..d8310b2475 100644 --- a/src/improper.h +++ b/src/improper.h @@ -38,8 +38,6 @@ class Improper : protected Pointers { virtual double memory_usage(); protected: - double PI; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/pair_born.cpp b/src/pair_born.cpp index 406b95a0cc..271b7b1f7a 100644 --- a/src/pair_born.cpp +++ b/src/pair_born.cpp @@ -24,10 +24,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -269,7 +271,6 @@ double PairBorn::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; @@ -277,11 +278,11 @@ double PairBorn::init_one(int i, int j) double rc2 = rc*rc; double rc3 = rc2*rc; double rc5 = rc3*rc2; - etail_ij = 2.0*PI*all[0]*all[1] * + etail_ij = 2.0*MY_PI*all[0]*all[1] * (a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1* (rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] * + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] * (-a[i][j]*exp((sigma[i][j]-rc)/rho1) * (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5)); diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 0490f80eea..1a3464e27e 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -20,10 +20,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -249,17 +251,16 @@ double PairBuck::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index 51c179b889..a2f0784a3d 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -24,10 +24,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -304,17 +306,16 @@ double PairBuckCoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut_lj[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/pair_lj96_cut.cpp b/src/pair_lj96_cut.cpp index 76f808dd03..8eb9a3d9d5 100644 --- a/src/pair_lj96_cut.cpp +++ b/src/pair_lj96_cut.cpp @@ -29,10 +29,12 @@ #include "update.h" #include "integrate.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -589,15 +591,14 @@ double PairLJ96Cut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / (6.0*rc6); - ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (3.0*sig3 - 4.0*rc3) / (6.0*rc6); } diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp index 671d6420cf..44d86990df 100644 --- a/src/pair_lj_cut.cpp +++ b/src/pair_lj_cut.cpp @@ -29,10 +29,12 @@ #include "update.h" #include "integrate.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -583,15 +585,14 @@ double PairLJCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp index 1d311d4b72..c6973b2580 100644 --- a/src/pair_lj_cut_coul_cut.cpp +++ b/src/pair_lj_cut_coul_cut.cpp @@ -21,10 +21,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -300,15 +302,14 @@ double PairLJCutCoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 57110ac81c..10e69ba977 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -19,10 +19,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -259,7 +261,6 @@ double PairLJExpand::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double shiftcut = shift[i][j] - cut[i][j]; @@ -273,11 +274,11 @@ double PairLJExpand::init_one(int i, int j) double rc12 = rc11*shiftcut; double shift2 = shift[i][j]*shift[i][j]; double shift3 = shift2*shift[i][j]; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6*((-1.0/(9.0*rc9) + shift[i][j]/(5.0*rc10) - shift2/(11.0*rc11))*sig6 + 1.0/(3.0*rc3) - shift[i][j]/(2.0*rc4) + shift2/(5.0*rc5)); - ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6* ((-4.0/(3.0*rc9) + 18.0*shift[i][j]/(5.0*rc10) - 36.0*shift2/(11.0*rc11) + shift3/rc12)*sig6 + 2.0/rc3 - 9.0*shift[i][j]/(2.0*rc4) + diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index ce25f4a782..63f0b72b05 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -21,17 +21,16 @@ #include "force.h" #include "update.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ -PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) -{ - PI = 4.0*atan(1.0); -} +PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) {} /* ---------------------------------------------------------------------- */ @@ -95,9 +94,9 @@ void PairSoft::compute(int eflag, int vflag) if (rsq < cutsq[itype][jtype]) { r = sqrt(rsq); - arg = PI*r/cut[itype][jtype]; + arg = MY_PI*r/cut[itype][jtype]; if (r > 0.0) fpair = factor_lj * prefactor[itype][jtype] * - sin(arg) * PI/cut[itype][jtype]/r; + sin(arg) * MY_PI/cut[itype][jtype]/r; else fpair = 0.0; f[i][0] += delx*fpair; @@ -290,9 +289,9 @@ double PairSoft::single(int i, int j, int itype, int jtype, double rsq, double r,arg,philj; r = sqrt(rsq); - arg = PI*r/cut[itype][jtype]; + arg = MY_PI*r/cut[itype][jtype]; fforce = factor_lj * prefactor[itype][jtype] * - sin(arg) * PI/cut[itype][jtype]/r; + sin(arg) * MY_PI/cut[itype][jtype]/r; philj = prefactor[itype][jtype] * (1.0+cos(arg)); return factor_lj*philj; diff --git a/src/pair_soft.h b/src/pair_soft.h index 1558f899bc..5cb8950659 100644 --- a/src/pair_soft.h +++ b/src/pair_soft.h @@ -43,7 +43,6 @@ class PairSoft : public Pair { void *extract(char *, int &); protected: - double PI; double cut_global; double **prefactor; double **cut; diff --git a/src/set.h b/src/set.h index 5e1fd4e8c7..00e0c77de1 100644 --- a/src/set.h +++ b/src/set.h @@ -35,7 +35,6 @@ class Set : protected Pointers { int style,ivalue,newtype,count; int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag; double dvalue,xvalue,yvalue,zvalue,wvalue,fraction; - double PI; void selection(int); void set(int); diff --git a/src/thermo.cpp b/src/thermo.cpp index 5bd877191a..b52a5f3c9c 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -36,10 +36,12 @@ #include "kspace.h" #include "output.h" #include "timer.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; // customize a new keyword by adding to this list: @@ -147,8 +149,6 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) format_float_user = NULL; format_int_user = NULL; format_bigint_user = NULL; - - PI = 4.0*atan(1.0); } /* ---------------------------------------------------------------------- */ @@ -1894,7 +1894,7 @@ void Thermo::compute_cellalpha() double* h = domain->h; double cosalpha = (h[5]*h[4]+h[1]*h[3])/ sqrt((h[1]*h[1]+h[5]*h[5])*(h[2]*h[2]+h[3]*h[3]+h[4]*h[4])); - dvalue = acos(cosalpha)*180.0/PI; + dvalue = acos(cosalpha)*180.0/MY_PI; } } @@ -1910,7 +1910,7 @@ void Thermo::compute_cellbeta() double* h = domain->h; double cosbeta = h[4]/sqrt(h[2]*h[2]+h[3]*h[3]+h[4]*h[4]); - dvalue = acos(cosbeta)*180.0/PI; + dvalue = acos(cosbeta)*180.0/MY_PI; } } @@ -1926,6 +1926,6 @@ void Thermo::compute_cellgamma() double* h = domain->h; double cosgamma = h[5]/sqrt(h[1]*h[1]+h[5]*h[5]); - dvalue = acos(cosgamma)*180.0/PI; + dvalue = acos(cosgamma)*180.0/MY_PI; } } diff --git a/src/thermo.h b/src/thermo.h index 352209cb35..eeb758b8e7 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -96,8 +96,6 @@ class Thermo : protected Pointers { char **id_variable; // list of variable names int *variables; // list of Variable indices - double PI; - // private methods void allocate(); From ae247d982aec3bc859224055c27196455f3bd25c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:24:16 +0000 Subject: [PATCH 201/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7137 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pair_hybrid.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index c23d694275..206782be27 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -195,10 +195,11 @@ void PairHybrid::settings(int narg, char **arg) allocated = 0; // count sub-styles by skipping numeric args - // exception is 1st arg of style "table", which is non-numeric word - // exception is 1st two args of style "lj/coul", which are non-numeric - // exception is 1st two args of style "buck/coul", which are non-numeric + // exception is 1st arg of table style, which is non-numeric word + // exception is 1st two args of lj/coul style, which are non-numeric + // exception is 1st two args of buck/coul, which are non-numeric // exception is 1st arg of reax/c style, which is non-numeric + // execption is 1st 6 args of gran styles, which can have NULLs // need a better way to skip these exceptions nstyles = 0; @@ -208,6 +209,8 @@ void PairHybrid::settings(int narg, char **arg) if (strcmp(arg[i],"lj/coul") == 0) i += 2; if (strcmp(arg[i],"buck/coul") == 0) i += 2; if (strcmp(arg[i],"reax/c") == 0) i++; + if (strstr(arg[i],"gran/hooke")) i += 6; + if (strstr(arg[i],"gran/hertz")) i += 6; i++; while (i < narg && !isalpha(arg[i][0])) i++; nstyles++; @@ -220,10 +223,11 @@ void PairHybrid::settings(int narg, char **arg) // allocate each sub-style and call its settings() with subset of args // define subset of args for a sub-style by skipping numeric args - // exception is 1st arg of style "table", which is non-numeric - // exception is 1st two args of style "lj/coul", which are non-numeric - // exception is 1st two args of style "buck/coul", which are non-numeric + // exception is 1st arg of table style, which is non-numeric word + // exception is 1st two args of lj/coul style, which are non-numeric + // exception is 1st two args of buck/coul, which are non-numeric // exception is 1st arg of reax/c style, which is non-numeric + // execption is 1st 6 args of gran styles, which can have NULLs // need a better way to skip these exceptions int dummy; @@ -246,6 +250,8 @@ void PairHybrid::settings(int narg, char **arg) if (strcmp(arg[i],"lj/coul") == 0) i += 2; if (strcmp(arg[i],"buck/coul") == 0) i += 2; if (strcmp(arg[i],"reax/c") == 0) i++; + if (strstr(arg[i],"gran/hooke")) i += 6; + if (strstr(arg[i],"gran/hertz")) i += 6; i++; while (i < narg && !isalpha(arg[i][0])) i++; styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]); From 497290eadc9c14902a964956129cf929c8c6cf75 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:25:36 +0000 Subject: [PATCH 202/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7138 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index ca89fa4bf8..78212f2ce3 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "12 Oct 2011" +#define LAMMPS_VERSION "19 Oct 2011" From 1049b963d7aad64f55a6410d4fd5748f0b5379d2 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:32:41 +0000 Subject: [PATCH 203/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7140 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/cuda_pair.cu | 6 ++++++ lib/cuda/cuda_pair_kernel.cu | 30 ++++++++++++++------------ lib/cuda/cuda_pair_virial_kernel_nc.cu | 2 +- lib/cuda/cuda_precision.h | 25 ++++++++++++++++----- lib/cuda/cuda_shared.h | 3 ++- lib/cuda/neighbor.cu | 4 ++-- lib/cuda/neighbor_kernel.cu | 21 ++++++++++-------- 7 files changed, 59 insertions(+), 32 deletions(-) diff --git a/lib/cuda/cuda_pair.cu b/lib/cuda/cuda_pair.cu index 531db7e2b3..b7b2523529 100644 --- a/lib/cuda/cuda_pair.cu +++ b/lib/cuda/cuda_pair.cu @@ -36,6 +36,9 @@ enum COUL_FORCES {COUL_NONE,COUL_CHARMM,COUL_CHARMM_IMPLICIT,COUL_CUT,COUL_LONG, #define DATA_V_RADIUS 512 #define DATA_OMEGA_RMASS 1024 +#define SBBITS 30 +#define NEIGHMASK 0x3FFFFFFF + #define MY_PREFIX cuda_pair #define IncludeCommonNeigh #include "cuda_shared.h" @@ -858,6 +861,9 @@ void Cuda_Pair_PostKernel_AllStyles(cuda_shared_data* sdata, dim3& grid, int& sh #include "cuda_pair_kernel.cu" +#include "pair_manybody_const.h" +#include "pair_tersoff_cuda.cu" +#include "pair_sw_cuda.cu" void Cuda_Pair_UpdateNmax(cuda_shared_data* sdata) { diff --git a/lib/cuda/cuda_pair_kernel.cu b/lib/cuda/cuda_pair_kernel.cu index fe7a38a782..35a0ef1f1a 100644 --- a/lib/cuda/cuda_pair_kernel.cu +++ b/lib/cuda/cuda_pair_kernel.cu @@ -20,7 +20,6 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -29,6 +28,10 @@ #define A4 -1.453152027 #define A5 1.061405429 +inline __device__ int sbmask(int j) { + return j >> SBBITS & 3; +} + template __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_atom) { @@ -88,8 +91,8 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at fytmp = F_F(0.0); fztmp = F_F(0.0); - if(coul_type!=COUL_NONE) - qtmp = fetchQ(i); + if(coul_type!=COUL_NONE) + qtmp = fetchQ(i); jnum = _numneigh[i]; jlist = &_neighbors[i]; @@ -103,10 +106,10 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at { fpair=F_F(0.0); j = jlist[jj*_nlocal]; - factor_lj = j<_nall ? F_F(1.0) : _special_lj[j/_nall]; - if(coul_type!=COUL_NONE) - factor_coul = j<_nall ? F_F(1.0) : _special_coul[j/_nall]; - j = j<_nall ? j : j % _nall; + factor_lj = _special_lj[sbmask(j)]; + if(coul_type!=COUL_NONE) + factor_coul = _special_coul[sbmask(j)]; + j &= NEIGHMASK; myxtype = fetchXType(j); delx = xtmp - myxtype.x; @@ -230,7 +233,6 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at fpair += forcecoul*r2inv; } break; - } } in_cutoff=in_cutoff || in_coul_cutoff; @@ -388,12 +390,12 @@ template nex_mol|sneighlist->nex_group|sneighlist->nex_type; if(exclude) NeighborBuildFullBin_Kernel<1><<>> - (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom); + (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall); else NeighborBuildFullBin_Kernel<0><<>> - (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom); + (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall); } //NeighborBuildFullBin_Kernel_Restrict<<>> // (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff); diff --git a/lib/cuda/neighbor_kernel.cu b/lib/cuda/neighbor_kernel.cu index ad1a6a8fe7..965aa2b1cf 100644 --- a/lib/cuda/neighbor_kernel.cu +++ b/lib/cuda/neighbor_kernel.cu @@ -21,6 +21,8 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ +#define SBBITS 30 + __global__ void Binning_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,int bin_dim_z, CUDA_FLOAT rez_bin_size_x,CUDA_FLOAT rez_bin_size_y,CUDA_FLOAT rez_bin_size_z) { @@ -109,8 +111,9 @@ __device__ inline int find_special(int3 &n, int* list,int & tag,int3 flag) } template -__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style) +__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style, bool neighall) { + int natoms = neighall?_nall:_nlocal; //const bool domol=false; int bin_dim_z=gridDim.y; CUDA_FLOAT* binned_x=(CUDA_FLOAT*) _buffer; @@ -152,7 +155,7 @@ __global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_ int jnum=0; int itype; - if(i<_nlocal) + if(i _maxneighbors) ((int*)_buffer)[0] = -jnum; - if(i<_nlocal) + if(i0) { if(block_style) - _neighbors[i*_maxneighbors+k]=j+which*_nall; + _neighbors[i*_maxneighbors+k]=j ^ (which << SBBITS); else - _neighbors[i+k*_nlocal]=j+which*_nall; + _neighbors[i+k*_nlocal]=j ^ (which << SBBITS); } else if(which<0) { From dcbe4d90bac3d1b6d7215e691ce48dea395a55f7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:32:57 +0000 Subject: [PATCH 204/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7141 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/pair_sw_cuda.cu | 140 +++ lib/cuda/pair_sw_cuda_cu.h | 39 + lib/cuda/pair_sw_cuda_kernel_nc.cu | 449 ++++++++++ lib/cuda/pair_tersoff_cuda.cu | 155 ++++ lib/cuda/pair_tersoff_cuda_cu.h | 42 + lib/cuda/pair_tersoff_cuda_kernel_nc.cu | 1054 +++++++++++++++++++++++ 6 files changed, 1879 insertions(+) create mode 100644 lib/cuda/pair_sw_cuda.cu create mode 100644 lib/cuda/pair_sw_cuda_cu.h create mode 100644 lib/cuda/pair_sw_cuda_kernel_nc.cu create mode 100644 lib/cuda/pair_tersoff_cuda.cu create mode 100644 lib/cuda/pair_tersoff_cuda_cu.h create mode 100644 lib/cuda/pair_tersoff_cuda_kernel_nc.cu diff --git a/lib/cuda/pair_sw_cuda.cu b/lib/cuda/pair_sw_cuda.cu new file mode 100644 index 0000000000..f5b0807fcd --- /dev/null +++ b/lib/cuda/pair_sw_cuda.cu @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include + +#include "pair_sw_cuda_cu.h" +__device__ __constant__ ParamSW_Float params_sw[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR]; + +#include "pair_sw_cuda_kernel_nc.cu" + +#include + + +void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h) +{ + unsigned cuda_ntypes = sdata->atom.ntypes + 1; + X_FLOAT box_size[3] = + { + sdata->domain.subhi[0] - sdata->domain.sublo[0], + sdata->domain.subhi[1] - sdata->domain.sublo[1], + sdata->domain.subhi[2] - sdata->domain.sublo[2] + }; + + cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3); + cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) ); + cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 ); + cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) ); + cudaMemcpyToSymbol("params_sw", params_host , sizeof(ParamSW_Float)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes ); + cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int)); +} + +void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom) +{ + static int glob_ij_size=0; + static F_FLOAT4* glob_r_ij=NULL; + static int* glob_numneigh_red=NULL; + static int* glob_neighbors_red=NULL; + static int* glob_neightype_red=NULL; + + if(glob_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT)) + { + glob_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT); + cudaFree(glob_r_ij); + cudaFree(glob_numneigh_red); + cudaFree(glob_neighbors_red); + cudaFree(glob_neightype_red); + cudaMalloc(&glob_r_ij,glob_ij_size*4); + cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int)); + cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) ); + } + dim3 grid,threads; + int sharedperproc; + + Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64); + cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams(); + + + + dim3 grid2; + if(sdata->atom.nall<=256*64000){ + grid2.x = (sdata->atom.nall+255)/256; + grid2.y = 1; + } else { + grid2.x = (sdata->atom.nall+256*128-1)/(256*128); + grid2.y = 128; + } + grid2.z = 1; + dim3 threads2; + threads2.x = 256; + threads2.y = 1; + threads2.z = 1; + + timespec time1,time2; + + //pre-calculate all neighbordistances and zeta_ij + clock_gettime(CLOCK_REALTIME,&time1); + Pair_SW_Kernel_TpA_RIJ<<>>(); + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test1+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + clock_gettime(CLOCK_REALTIME,&time1); + + //actual force calculation + unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure + if(eflag) + { + if(vflag) + Pair_SW_Kernel_TpA<1,1><<>> + (eflag_atom,vflag_atom); + else + Pair_SW_Kernel_TpA<1,0><<>> + (eflag_atom,vflag_atom); + } + else + { + if(vflag) + Pair_SW_Kernel_TpA<0,1><<>> + (eflag_atom,vflag_atom); + else + Pair_SW_Kernel_TpA<0,0><<>> + (eflag_atom,vflag_atom); + } + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test2+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + + Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag); +} + diff --git a/lib/cuda/pair_sw_cuda_cu.h b/lib/cuda/pair_sw_cuda_cu.h new file mode 100644 index 0000000000..24e92689ff --- /dev/null +++ b/lib/cuda/pair_sw_cuda_cu.h @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include "cuda_shared.h" + + struct ParamSW_Float { + F_FLOAT epsilon,sigma; + F_FLOAT littlea,lambda,gamma,costheta; + F_FLOAT biga,bigb; + F_FLOAT powerp,powerq; + F_FLOAT tol; + F_FLOAT cut,cutsq; + F_FLOAT sigma_gamma,lambda_epsilon,lambda_epsilon2; + F_FLOAT c1,c2,c3,c4,c5,c6; + int ielement,jelement,kelement; + }; + +extern "C" void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h); +extern "C" void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom); diff --git a/lib/cuda/pair_sw_cuda_kernel_nc.cu b/lib/cuda/pair_sw_cuda_kernel_nc.cu new file mode 100644 index 0000000000..8072822559 --- /dev/null +++ b/lib/cuda/pair_sw_cuda_kernel_nc.cu @@ -0,0 +1,449 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ +#define Pi F_F(3.1415926535897932384626433832795) +#define PI Pi +#define PI2 F_F(0.5)*Pi +#define PI4 F_F(0.25)*Pi + + + +__device__ void twobody(int iparam, F_FLOAT rsq, F_FLOAT &fforce, + int eflag, ENERGY_FLOAT &eng) +{ + F_FLOAT r,rp,rq,rainv,expsrainv; + + r = sqrt(rsq); + rp = pow(r,-params_sw[iparam].powerp); + rq = pow(r,-params_sw[iparam].powerq); + rainv = 1.0 / (r - params_sw[iparam].cut); + expsrainv = exp(params_sw[iparam].sigma * rainv); + fforce = (params_sw[iparam].c1*rp - params_sw[iparam].c2*rq + + (params_sw[iparam].c3*rp -params_sw[iparam].c4*rq) * rainv*rainv*r) * expsrainv / rsq; + if (eflag) eng += (params_sw[iparam].c5*rp - params_sw[iparam].c6*rq) * expsrainv; +} + +__device__ void threebody(int paramij, int paramik, int paramijk, + F_FLOAT4& delr1, + F_FLOAT4& delr2, + F_FLOAT3& fj, F_FLOAT3& fk, int eflag,ENERGY_FLOAT &eng) +{ + F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1; + F_FLOAT r2,rinvsq2,rainv2,gsrainv2,gsrainvsq2,expgsrainv2; + F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1,frad2; + F_FLOAT facang,facang12,csfacang,csfac1,csfac2; + + r1 = sqrt(delr1.w); + rinvsq1 = F_F(1.0)/delr1.w; + rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut); + gsrainv1 = params_sw[paramij].sigma_gamma * rainv1; + gsrainvsq1 = gsrainv1*rainv1/r1; + expgsrainv1 = exp(gsrainv1); + + r2 = sqrt(delr2.w); + rinvsq2 = F_F(1.0)/delr2.w; + rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut); + gsrainv2 = params_sw[paramik].sigma_gamma * rainv2; + gsrainvsq2 = gsrainv2*rainv2/r2; + expgsrainv2 = exp(gsrainv2); + + rinv12 = F_F(1.0)/(r1*r2); + cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12; + delcs = cs - params_sw[paramijk].costheta; + delcssq = delcs*delcs; + + facexp = expgsrainv1*expgsrainv2; + + // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) * + // facexp*delcssq; + + facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq; + frad1 = facrad*gsrainvsq1; + frad2 = facrad*gsrainvsq2; + facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs; + facang12 = rinv12*facang; + csfacang = cs*facang; + csfac1 = rinvsq1*csfacang; + + fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12; + fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12; + fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12; + + csfac2 = rinvsq2*csfacang; + + fk.x = delr2.x*(frad2+csfac2)-delr1.x*facang12; + fk.y = delr2.y*(frad2+csfac2)-delr1.y*facang12; + fk.z = delr2.z*(frad2+csfac2)-delr1.z*facang12; + + if (eflag) eng+= F_F(2.0)*facrad; +} + +__device__ void threebody_fj(int paramij, int paramik, int paramijk, + F_FLOAT4& delr1, + F_FLOAT4& delr2, + F_FLOAT3& fj) +{ + F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1; + F_FLOAT r2,rainv2,gsrainv2,expgsrainv2; + F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1; + F_FLOAT facang,facang12,csfacang,csfac1; + + r1 = sqrt(delr1.w); + rinvsq1 = F_F(1.0)/delr1.w; + rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut); + gsrainv1 = params_sw[paramij].sigma_gamma * rainv1; + gsrainvsq1 = gsrainv1*rainv1/r1; + expgsrainv1 = exp(gsrainv1); + + r2 = sqrt(delr2.w); + rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut); + gsrainv2 = params_sw[paramik].sigma_gamma * rainv2; + expgsrainv2 = exp(gsrainv2); + + rinv12 = F_F(1.0)/(r1*r2); + cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12; + delcs = cs - params_sw[paramijk].costheta; + delcssq = delcs*delcs; + + facexp = expgsrainv1*expgsrainv2; + + // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) * + // facexp*delcssq; + + facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq; + frad1 = facrad*gsrainvsq1; + facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs; + facang12 = rinv12*facang; + csfacang = cs*facang; + csfac1 = rinvsq1*csfacang; + + fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12; + fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12; + fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12; +} + + +__global__ void Pair_SW_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + X_FLOAT4 myxtype; + F_FLOAT4 delij; + F_FLOAT xtmp,ytmp,ztmp; + int itype,jnum,i,j; + int* jlist; + int neigh_red = 0; + i = ii;//_ilist[ii]; + myxtype = fetchXType(i); + + xtmp=myxtype.x; + ytmp=myxtype.y; + ztmp=myxtype.z; + itype=map[(static_cast (myxtype.w))]; + + jnum = _numneigh[i]; + jlist = &_neighbors[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj (myxtype.w))]; + int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + delij.w = vec3_dot(delij,delij); + if (delij.w < params_sw[iparam_ij].cutsq) + { + _glob_neighbors_red[i+neigh_red*_nall]=j; + _glob_neightype_red[i+neigh_red*_nall]=jtype; + _glob_r_ij[i+neigh_red*_nall]=delij; + neigh_red++; + } + } + } + _glob_numneigh_red[i]=neigh_red; +} + + + template + __global__ void Pair_SW_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + ENERGY_FLOAT evdwl = ENERGY_F(0.0); + + ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x]; + ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x]; + + F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem; + if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x]; + else + if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x]; + else + if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x]; + shared_F_F+=threadIdx.x; + + if(eflag_atom||eflag) + { + sharedE[0] = ENERGY_F(0.0); + sharedV += blockDim.x; + } + + if(vflagm||vflag_atom) + { + sharedV[0*blockDim.x] = ENERGY_F(0.0); + sharedV[1*blockDim.x] = ENERGY_F(0.0); + sharedV[2*blockDim.x] = ENERGY_F(0.0); + sharedV[3*blockDim.x] = ENERGY_F(0.0); + sharedV[4*blockDim.x] = ENERGY_F(0.0); + sharedV[5*blockDim.x] = ENERGY_F(0.0); + } + + int jnum_red=0; +#define fxtmp shared_F_F[0] +#define fytmp shared_F_F[blockDim.x] +#define fztmp shared_F_F[2*blockDim.x] +//#define jnum_red (static_cast (shared_F_F[3*blockDim.x])) + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + X_FLOAT4 myxtype_i,myxtype_j,myxtype_k; + F_FLOAT4 delij,delik,deljk; + F_FLOAT fpair; + + int itype,i,j; + int* jlist_red; + + if(ii < _inum) + { + i = _ilist[ii]; + + if(vflagm) + myxtype_i=fetchXType(i); + //itype=map[(static_cast (myxtype_i.w))]; + itype=map[_type[i]]; + + + fxtmp = F_F(0.0); + fytmp = F_F(0.0); + fztmp = F_F(0.0); + + + //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i]; + jnum_red = _glob_numneigh_red[i]; + jlist_red = &_glob_neighbors_red[i]; + } + __syncthreads(); +#pragma unroll 1 + for (int jj = 0; jj < jnum_red; jj++) + { + if(i < _nlocal) + { + fpair=F_F(0.0); + j = jlist_red[jj*_nall]; + j &= NEIGHMASK; + + if(vflagm) + myxtype_j = fetchXType(j); + + int jtype = _glob_neightype_red[i+jj*_nall]; + delij = _glob_r_ij[i+jj*_nall]; + + volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype]; + + if (delij.w(); +#undef fxtmp +#undef fytmp +#undef fztmp +//#undef jnum_red +} diff --git a/lib/cuda/pair_tersoff_cuda.cu b/lib/cuda/pair_tersoff_cuda.cu new file mode 100644 index 0000000000..abbf39ecf0 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda.cu @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include + + +#include "pair_tersoff_cuda_cu.h" +__device__ __constant__ Param_Float params[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR]; +__device__ __constant__ F_FLOAT* _glob_zeta_ij; //zeta_ij +__device__ __constant__ F_FLOAT4* _glob_r_ij; //r_ij (x,y,z,r^2) for pairs within force cutoff +__device__ __constant__ bool _zbl; //is tersoff zbl? + + +#include "pair_tersoff_cuda_kernel_nc.cu" + +#include + + +void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl) +{ + unsigned cuda_ntypes = sdata->atom.ntypes + 1; + X_FLOAT box_size[3] = + { + sdata->domain.subhi[0] - sdata->domain.sublo[0], + sdata->domain.subhi[1] - sdata->domain.sublo[1], + sdata->domain.subhi[2] - sdata->domain.sublo[2] + }; + + cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3); + cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) ); + cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 ); + cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) ); + cudaMemcpyToSymbol("params", params_host , sizeof(Param_Float)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes ); + cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int)); + cudaMemcpyToSymbol("_zbl",&zbl,sizeof(bool)); + +} + +void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom) +{ + static F_FLOAT* glob_zeta_ij=NULL; + static int glob_zeta_ij_size=0; + static F_FLOAT4* glob_r_ij=NULL; + static int* glob_numneigh_red=NULL; + static int* glob_neighbors_red=NULL; + static int* glob_neightype_red=NULL; + + if(glob_zeta_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT)) + { + glob_zeta_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT); + cudaFree(glob_zeta_ij); + cudaFree(glob_r_ij); + cudaFree(glob_numneigh_red); + cudaFree(glob_neighbors_red); + cudaFree(glob_neightype_red); + cudaMalloc(&glob_zeta_ij,glob_zeta_ij_size); + cudaMalloc(&glob_r_ij,glob_zeta_ij_size*4); + cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int)); + cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) ); + cudaMemcpyToSymbol("_glob_zeta_ij", &glob_zeta_ij , sizeof(F_FLOAT*) ); + } + dim3 grid,threads; + int sharedperproc; + + Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64); + cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams(); + + + + dim3 grid2; + if(sdata->atom.nall<=256*64000){ + grid2.x = (sdata->atom.nall+255)/256; + grid2.y = 1; + } else { + grid2.x = (sdata->atom.nall+256*128-1)/(256*128); + grid2.y = 128; + } + grid2.z = 1; + dim3 threads2; + threads2.x = 256; + threads2.y = 1; + threads2.z = 1; + + timespec time1,time2; + + //pre-calculate all neighbordistances and zeta_ij + clock_gettime(CLOCK_REALTIME,&time1); + Pair_Tersoff_Kernel_TpA_RIJ<<>> + (); + cudaThreadSynchronize(); + Pair_Tersoff_Kernel_TpA_ZetaIJ<<>> + (); + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test1+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + clock_gettime(CLOCK_REALTIME,&time1); + + //actual force calculation + unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure + if(eflag) + { + if(vflag) + Pair_Tersoff_Kernel_TpA<1,1><<>> + (eflag_atom,vflag_atom); + else + Pair_Tersoff_Kernel_TpA<1,0><<>> + (eflag_atom,vflag_atom); + } + else + { + if(vflag) + Pair_Tersoff_Kernel_TpA<0,1><<>> + (eflag_atom,vflag_atom); + else + Pair_Tersoff_Kernel_TpA<0,0><<>> + (eflag_atom,vflag_atom); + } + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test2+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + + Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag); +} + diff --git a/lib/cuda/pair_tersoff_cuda_cu.h b/lib/cuda/pair_tersoff_cuda_cu.h new file mode 100644 index 0000000000..5276cd1c35 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda_cu.h @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include "cuda_shared.h" + + struct Param_Float { + F_FLOAT lam1,lam2,lam3; + F_FLOAT c,d,h; + F_FLOAT gamma,powerm; + F_FLOAT powern,beta; + F_FLOAT biga,bigb,bigd,bigr; + F_FLOAT cut,cutsq; + F_FLOAT c1,c2,c3,c4; + int ielement,jelement,kelement; + int powermint; + //F_FLOAT Z_i,Z_j; + F_FLOAT ZBLcut,ZBLexpscale; + F_FLOAT a_ij,premult; + }; + +extern "C" void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl); +extern "C" void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom); diff --git a/lib/cuda/pair_tersoff_cuda_kernel_nc.cu b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu new file mode 100644 index 0000000000..f94f35a587 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu @@ -0,0 +1,1054 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ +#define Pi F_F(3.1415926535897932384626433832795) +#define PI Pi +#define PI2 F_F(0.5)*Pi +#define PI4 F_F(0.25)*Pi +template +static inline __device__ void PairVirialCompute_A_Kernel_Template() +{ + __syncthreads(); + ENERGY_FLOAT* shared=sharedmem; + + if(eflag) + { + reduceBlock(shared); + shared+=blockDim.x; + } + if(vflag) + { + reduceBlock(shared + 0 * blockDim.x); + reduceBlock(shared + 1 * blockDim.x); + reduceBlock(shared + 2 * blockDim.x); + reduceBlock(shared + 3 * blockDim.x); + reduceBlock(shared + 4 * blockDim.x); + reduceBlock(shared + 5 * blockDim.x); + } + if(threadIdx.x == 0) + { + shared=sharedmem; + ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer; + if(eflag) + { + buffer[blockIdx.x * gridDim.y + blockIdx.y] = ENERGY_F(0.5)*shared[0]; + shared+=blockDim.x; buffer+=gridDim.x * gridDim.y; + } + if(vflag) + { + buffer[blockIdx.x * gridDim.y + blockIdx.y + 0 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[0 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 1 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[1 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 2 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[2 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 3 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[3 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 4 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[4 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 5 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[5 * blockDim.x]; + } + } + __syncthreads(); +} + +__global__ void virial_fdotr_compute_kernel(int eflag) +{ + int i = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + ENERGY_FLOAT* sharedE = (ENERGY_FLOAT*) &sharedmem[0]; + ENERGY_FLOAT* sharedVirial = (ENERGY_FLOAT*) &sharedE[blockDim.x]; + sharedE+=threadIdx.x; + sharedVirial+=threadIdx.x; + if(i<_nlocal) + { + + F_FLOAT x = _x[i]; + F_FLOAT y = _x[i+_nmax]; + F_FLOAT z = _x[i+2*_nmax]; + F_FLOAT fx = _f[i]; + F_FLOAT fy = _f[i+_nmax]; + F_FLOAT fz = _f[i+2*_nmax]; + //if(fz*z*fz*z>1e-5) printf("V %i %i %e %e %e %e %e %e\n",i,_tag[i],x,y,z,fx,fy,fz); + sharedVirial[0] = fx*x; + sharedVirial[1*blockDim.x] = fy*y; + sharedVirial[2*blockDim.x] = fz*z; + sharedVirial[3*blockDim.x] = fy*x; + sharedVirial[4*blockDim.x] = fz*x; + sharedVirial[5*blockDim.x] = fz*y; + } else { + sharedVirial[0] = 0; + sharedVirial[1*blockDim.x] = 0; + sharedVirial[2*blockDim.x] = 0; + sharedVirial[3*blockDim.x] = 0; + sharedVirial[4*blockDim.x] = 0; + sharedVirial[5*blockDim.x] = 0; + } + sharedVirial = (ENERGY_FLOAT*) &sharedmem[0]; + sharedVirial += blockDim.x; + reduceBlockP2(sharedVirial); + reduceBlockP2(&sharedVirial[1*blockDim.x]); + reduceBlockP2(&sharedVirial[2*blockDim.x]); + reduceBlockP2(&sharedVirial[3*blockDim.x]); + reduceBlockP2(&sharedVirial[4*blockDim.x]); + reduceBlockP2(&sharedVirial[5*blockDim.x]); + if(threadIdx.x<6) + { + ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer; + if(eflag) buffer = &buffer[gridDim.x*gridDim.y]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + threadIdx.x * gridDim.x * gridDim.y]= sharedVirial[threadIdx.x*blockDim.x]; + } +} + +/*#define vec3_scale(K,X,Y) Y.x = K*X.x; Y.y = K*X.y; Y.z = K*X.z; +#define vec3_scaleadd(K,X,Y,Z) Z.x = K*X.x+Y.x; Z.y = K*X.y+Y.y; Z.z = K*X.z+Y.z; +#define vec3_add(X,Y,Z) Z.x = X.x+Y.x; Z.y = X.y+Y.y; Z.z = X.z+Y.z; +#define vec3_dot(X,Y) (X.x*Y.x + X.y*Y.y + X.z*Y.z)*/ + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT3& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT4& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scaleadd(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) { + z.x = k*x.x+y.x; z.y = k*x.y+y.y; z.z = k*x.z+y.z; +} + +__device__ inline void vec3_add(F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) { + z.x = x.x+y.x; z.y = x.y+y.y; z.z = x.z+y.z; +} + +__device__ inline F_FLOAT vec3_dot(F_FLOAT3 x, F_FLOAT3 y) { + return x.x*y.x + x.y*y.y + x.z*y.z; +} + +__device__ inline F_FLOAT vec3_dot(F_FLOAT4 x, F_FLOAT4 y) { + return x.x*y.x + x.y*y.y + x.z*y.z; +} + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function +------------------------------------------------------------------------- */ + +__device__ inline F_FLOAT F_fermi(F_FLOAT &r, int &iparam) +{ + return F_F(1.0) / (F_F(1.0) + exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut))); +} + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function derivative with respect to r +------------------------------------------------------------------------- */ + +__device__ inline F_FLOAT F_fermi_d(F_FLOAT &r, int &iparam) +{ + volatile const F_FLOAT tmp = exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut)); + return params[iparam].ZBLexpscale*tmp / + ((F_F(1.0) +tmp)*(F_F(1.0) +tmp)); +} + +__device__ inline F_FLOAT ters_fc(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D) +{ + return (r < ters_R-ters_D)?F_F(1.0):((r > ters_R+ters_D)? + F_F(0.0):F_F(0.5)*(F_F(1.0) - sin(PI2*(r - ters_R)/ters_D))); +} + +__device__ inline F_FLOAT ters_fc_d(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D) +{ + return ((r < ters_R-ters_D)||(r > ters_R+ters_D))? + F_F(0.0):-(PI4/ters_D) * cos(PI2*(r - ters_R)/ters_D); +} + + +__device__ inline F_FLOAT ters_gijk(F_FLOAT& cos_theta, int iparam) +{ + F_FLOAT ters_c = params[iparam].c; + F_FLOAT ters_d = params[iparam].d; + + return params[iparam].gamma*(F_F(1.0) + pow(params[iparam].c/params[iparam].d,F_F(2.0)) - + pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0)))); +} + +__device__ F_FLOAT ters_gijk2(F_FLOAT& cos_theta, int iparam) +{ + F_FLOAT ters_c = params[iparam].c; + F_FLOAT ters_d = params[iparam].d; + + return params[iparam].gamma*(F_F(1.0) + pow(ters_c/ters_d,F_F(2.0)) - + pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0)))); +} + +__device__ inline F_FLOAT ters_gijk_d(F_FLOAT costheta, int iparam) +{ + F_FLOAT numerator = -F_F(2.0) * pow(params[iparam].c,F_F(2.0)) * (params[iparam].h - costheta); + F_FLOAT denominator = pow(pow(params[iparam].d,F_F(2.0)) + + pow(params[iparam].h - costheta,F_F(2.0)),F_F(2.0)); + return params[iparam].gamma*numerator/denominator; +} + +__device__ inline F_FLOAT zeta(int iparam, const F_FLOAT rsqij, const F_FLOAT rsqik, + F_FLOAT3& delij, F_FLOAT3& delik) +{ + F_FLOAT rij,rik,costheta,arg,ex_delr; + + rij = sqrt(rsqij); + rik = sqrt(rsqik); + costheta = vec3_dot(delij,delik) / (rij*rik); + + arg = (params[iparam].powermint == 3)? (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)) : params[iparam].lam3 * (rij-rik); + + if (arg > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (arg < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(arg); + + return ters_fc(rik,params[iparam].bigr,params[iparam].bigd) * ex_delr * params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c/(params[iparam].d*params[iparam].d)) - + (params[iparam].c*params[iparam].c) / ((params[iparam].d*params[iparam].d) + (params[iparam].h - costheta)*(params[iparam].h - costheta))); +} + +__device__ void repulsive(int iparam, F_FLOAT rsq, F_FLOAT &fforce, + int eflag, ENERGY_FLOAT &eng) +{ + F_FLOAT r,tmp_fc,tmp_fc_d,tmp_exp; + + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + tmp_fc = ters_fc(r,ters_R,ters_D); + tmp_fc_d = ters_fc_d(r,ters_R,ters_D); + tmp_exp = exp(-params[iparam].lam1 * r); + if(!_zbl) + { + fforce = -params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1) / r; + if (eflag) eng += tmp_fc * params[iparam].biga * tmp_exp; + } + else + { + F_FLOAT const fforce_ters = params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1); + ENERGY_FLOAT eng_ters = tmp_fc * params[iparam].biga * tmp_exp; + + F_FLOAT r_ov_a = r/params[iparam].a_ij; + F_FLOAT phi = F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) + F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) + + F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) + F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a); + F_FLOAT dphi = (F_F(1.0)/params[iparam].a_ij) * (-F_F(3.2)*F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) - + F_F(0.9423)*F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) - + F_F(0.4029)*F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) - + F_F(0.2016)*F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a)); + F_FLOAT fforce_ZBL = params[iparam].premult/(-r*r)* phi + params[iparam].premult/r*dphi; + ENERGY_FLOAT eng_ZBL = params[iparam].premult*(F_F(1.0)/r)*phi; + + fforce = -(-F_fermi_d(r,iparam) * (eng_ZBL - eng_ters) + fforce_ZBL + F_fermi(r,iparam)*(fforce_ters-fforce_ZBL))/r; + if(eflag) + eng += eng_ZBL + F_fermi(r,iparam)*(eng_ters-eng_ZBL); + } + + +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_fa(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D) +{ + if (r > ters_R + ters_D) return F_F(0.0); + if(_zbl) + return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D) * F_fermi(r,iparam); + else + return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_fa_d(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D) +{ + if (r > ters_R + ters_D) return F_F(0.0); + if(_zbl) + return params[iparam].bigb * exp(-params[iparam].lam2 * r) * + ((params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D))*F_fermi(r,iparam) + -ters_fc(r,ters_R,ters_D)*F_fermi_d(r,iparam)); + else + return params[iparam].bigb * exp(-params[iparam].lam2 * r) * + (params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D)); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_bij(F_FLOAT zeta, int iparam) +{ + F_FLOAT tmp = params[iparam].beta * zeta; + if (tmp > params[iparam].c1) return F_F(1.0)/sqrt(tmp); + if (tmp > params[iparam].c2) + return (F_F(1.0) - pow(tmp,-params[iparam].powern) / (F_F(2.0)*params[iparam].powern))/sqrt(tmp); + if (tmp < params[iparam].c4) return F_F(1.0); + if (tmp < params[iparam].c3) + return F_F(1.0) - pow(tmp,params[iparam].powern)/(F_F(2.0)*params[iparam].powern); + return pow(F_F(1.0) + pow(tmp,params[iparam].powern), -F_F(1.0)/(F_F(2.0)*params[iparam].powern)); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_bij_d(F_FLOAT zeta, int iparam) +{ + F_FLOAT tmp = params[iparam].beta * zeta; + if (tmp > params[iparam].c1) return params[iparam].beta * -F_F(0.5)*pow(tmp,-F_F(1.5)); + if (tmp > params[iparam].c2) + return params[iparam].beta * (-F_F(0.5)*pow(tmp,-F_F(1.5)) * + (F_F(1.0) - F_F(0.5)*(F_F(1.0) + F_F(1.0)/(F_F(2.0)*params[iparam].powern)) * + pow(tmp,-params[iparam].powern))); + if (tmp < params[iparam].c4) return F_F(0.0); + if (tmp < params[iparam].c3) + return -F_F(0.5)*params[iparam].beta * pow(tmp,params[iparam].powern-F_F(1.0)); + + F_FLOAT tmp_n = pow(tmp,params[iparam].powern); + return -F_F(0.5) * pow(F_F(1.0)+tmp_n, -F_F(1.0)-(F_F(1.0)/(F_F(2.0)*params[iparam].powern)))*tmp_n / zeta; +} + +__device__ void force_zeta(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &fforce, F_FLOAT &prefactor, + int eflag, F_FLOAT &eng) +{ + F_FLOAT r,fa,fa_d,bij; + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + fa = ters_fa(r,iparam,ters_R,ters_D); + fa_d = ters_fa_d(r,iparam,ters_R,ters_D); + bij = ters_bij(zeta_ij,iparam); + fforce = F_F(0.5)*bij*fa_d / r; + prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam); + if (eflag) eng += bij*fa; +} + +__device__ void force_zeta_prefactor_force(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &fforce, F_FLOAT &prefactor) +{ + F_FLOAT r,fa,fa_d,bij; + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + fa = ters_fa(r,iparam,ters_R,ters_D); + fa_d = ters_fa_d(r,iparam,ters_R,ters_D); + bij = ters_bij(zeta_ij,iparam); + fforce = F_F(0.5)*bij*fa_d / r; + prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam); +} + +__device__ void force_zeta_prefactor(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &prefactor) +{ + F_FLOAT r,fa; + r = sqrt(rsq); + fa = ters_fa(r,iparam,params[iparam].bigr,params[iparam].bigd); + prefactor = -F_F(0.5)*fa*ters_bij_d(zeta_ij,iparam); +} + + +__device__ void costheta_d(F_FLOAT3& rij_hat, F_FLOAT& rij, + F_FLOAT3& rik_hat, F_FLOAT& rik, + F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk) +{ + // first element is derivative wrt Ri, second wrt Rj, third wrt Rk + + F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj); + vec3_scale(F_F(1.0)/rij,drj,drj); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk); + vec3_scale(F_F(1.0)/rik,drk,drk); + vec3_add(drj,drk,dri); + vec3_scale(-F_F(1.0),dri,dri); +} + +__device__ void ters_zetaterm_d(F_FLOAT prefactor, + F_FLOAT3& rij_hat, F_FLOAT rij, + F_FLOAT3& rik_hat, F_FLOAT rik, + F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk, + int iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + F_FLOAT3 dcosdri,dcosdrj,dcosdrk; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + // dri = -dfc*gijk*ex_delr*rik_hat; + // dri += fc*gijk_d*ex_delr*dcosdri; + // dri += fc*gijk*ex_delr_d*(rik_hat - rij_hat); + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + + vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri); + vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri); + vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri); + vec3_scale(prefactor,dri,dri); + // compute the derivative wrt Rj + // drj = fc*gijk_d*ex_delr*dcosdrj; + // drj += fc*gijk*ex_delr_d*rij_hat; + + vec3_scale(fc*gijk_d*ex_delr,dcosdrj,drj); + vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj); + vec3_scale(prefactor,drj,drj); + + // compute the derivative wrt Rk + // drk = dfc*gijk*ex_delr*rik_hat; + // drk += fc*gijk_d*ex_delr*dcosdrk; + // drk += -fc*gijk*ex_delr_d*rik_hat; + + vec3_scale(dfc*gijk*ex_delr,rik_hat,drk); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdrk,drk,drk); + vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk); + vec3_scale(prefactor,drk,drk); +} + +__device__ void ters_zetaterm_d_fi(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& dri, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + //costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk); + + + F_FLOAT3 dcosdri; + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,dri); + vec3_scale(F_F(1.0)/rij,dri,dri); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,dcosdri); + vec3_scale(F_F(1.0)/rik,dcosdri,dcosdri); + vec3_add(dri,dcosdri,dcosdri); + vec3_scale(-F_F(1.0),dcosdri,dcosdri); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri +// + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri); + vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri); + vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri); + vec3_scale(prefactor,dri,dri); + +} + +__device__ void ters_zetaterm_d_fj(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& drj, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj); + vec3_scale(F_F(1.0)/rij,drj,drj); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(fc*gijk_d*ex_delr,drj,drj); + vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj); + vec3_scale(prefactor,drj,drj); +} + +__device__ void ters_zetaterm_d_fk(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& drk, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk); + vec3_scale(F_F(1.0)/rik,drk,drk); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(fc*gijk_d*ex_delr,drk,drk); + vec3_scaleadd(dfc*gijk*ex_delr,rik_hat,drk,drk); + vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk); + vec3_scale(prefactor,drk,drk); +} + +__device__ void attractive(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& fi, F_FLOAT3& fj, F_FLOAT3& fk) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d(prefactor,rij_hat,rij,rik_hat,rik,fi,fj,fk,iparam); +} + +__device__ void attractive_fi(int& iparam, F_FLOAT& prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fi(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__device__ void attractive_fj(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fj(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__device__ void attractive_fk(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fk(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__global__ void Pair_Tersoff_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + X_FLOAT4 myxtype; + F_FLOAT4 delij; + F_FLOAT xtmp,ytmp,ztmp; + int itype,jnum,i,j; + int* jlist; + int neigh_red = 0; + i = ii;//_ilist[ii]; + myxtype = fetchXType(i); + + xtmp=myxtype.x; + ytmp=myxtype.y; + ztmp=myxtype.z; + itype=map[(static_cast (myxtype.w))]; + + jnum = _numneigh[i]; + jlist = &_neighbors[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj (myxtype.w))]; + int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + delij.w = vec3_dot(delij,delij); + if (delij.w < params[iparam_ij].cutsq) + { + _glob_neighbors_red[i+neigh_red*_nall]=j; + _glob_neightype_red[i+neigh_red*_nall]=jtype; + _glob_r_ij[i+neigh_red*_nall]=delij; + neigh_red++; + } + } + } + _glob_numneigh_red[i]=neigh_red; +} + + + __global__ void Pair_Tersoff_Kernel_TpA_ZetaIJ()//F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) + { + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + + F_FLOAT4 delij; + F_FLOAT4 delik; + + int itype,jnum,i,j; + int* jlist; + i = ii; + itype=map[(static_cast (_type[i]))]; + + jnum = _glob_numneigh_red[i]; + jlist = &_glob_neighbors_red[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj + __global__ void Pair_Tersoff_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + ENERGY_FLOAT evdwl = ENERGY_F(0.0); + + ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x]; + ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x]; + + F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem; + if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x]; + else + if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x]; + else + if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x]; + shared_F_F+=threadIdx.x; + + if(eflag_atom||eflag) + { + sharedE[0] = ENERGY_F(0.0); + sharedV += blockDim.x; + } + + if(vflagm||vflag_atom) + { + sharedV[0*blockDim.x] = ENERGY_F(0.0); + sharedV[1*blockDim.x] = ENERGY_F(0.0); + sharedV[2*blockDim.x] = ENERGY_F(0.0); + sharedV[3*blockDim.x] = ENERGY_F(0.0); + sharedV[4*blockDim.x] = ENERGY_F(0.0); + sharedV[5*blockDim.x] = ENERGY_F(0.0); + } + + int jnum_red=0; +#define fxtmp shared_F_F[0] +#define fytmp shared_F_F[blockDim.x] +#define fztmp shared_F_F[2*blockDim.x] +//#define jnum_red (static_cast (shared_F_F[3*blockDim.x])) + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + + X_FLOAT4 myxtype_i,myxtype_j,myxtype_k; + F_FLOAT4 delij,delik,deljk; + F_FLOAT fpair; + F_FLOAT prefactor_ij,prefactor_ji; + + int itype,i,j; + int* jlist_red; + + if(ii < _inum) + { + i = _ilist[ii]; + + if(vflagm) + myxtype_i=fetchXType(i); + //itype=map[(static_cast (myxtype_i.w))]; + itype=map[_type[i]]; + + + fxtmp = F_F(0.0); + fytmp = F_F(0.0); + fztmp = F_F(0.0); + + + //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i]; + jnum_red = _glob_numneigh_red[i]; + jlist_red = &_glob_neighbors_red[i]; + } + __syncthreads(); + +#pragma unroll 1 + for (int jj = 0; jj < jnum_red; jj++) + { + if(i < _nlocal) + { + fpair=F_F(0.0); + j = jlist_red[jj*_nall]; + j &= NEIGHMASK; + + if(vflagm) + myxtype_j = fetchXType(j); + + int jtype = _glob_neightype_red[i+jj*_nall]; + delij = _glob_r_ij[i+jj*_nall]; + + volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype]; + + if (delij.w(); +#undef fxtmp +#undef fytmp +#undef fztmp +//#undef jnum_red +} From 10a6791ea2bf43dac404132f33e655ea2f1f6b74 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:33:50 +0000 Subject: [PATCH 205/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7142 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/cuda_common.h | 344 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 lib/cuda/cuda_common.h diff --git a/lib/cuda/cuda_common.h b/lib/cuda/cuda_common.h new file mode 100644 index 0000000000..d4687ebd06 --- /dev/null +++ b/lib/cuda/cuda_common.h @@ -0,0 +1,344 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#ifndef _CUDA_COMMON_H_ +#define _CUDA_COMMON_H_ + +//#include "cutil.h" +#include "cuda_precision.h" +#include "cuda_wrapper_cu.h" + +#define CUDA_MAX_TYPES_PLUS_ONE 12 //for pair styles which use constant space for parameters, this needs to be one larger than the number of atom types +//this can not be arbitrarly large, since constant space is limited. +//in principle one could alter potentials to use global memory for parameters, some du that already since the first examples I encountered had a high number (20+) of atom types +//Christian +#define CUDA_MAX_TYPES2 (CUDA_MAX_TYPES_PLUS_ONE * CUDA_MAX_TYPES_PLUS_ONE) +#define CUDA_MAX_NSPECIAL 25 + +// define some easy-to-use debug and emulation macros +#ifdef _DEBUG +#define MYDBG(a) a +#else +#define MYDBG(a) +#endif + +#if __DEVICE_EMULATION__ +#define MYEMU(a) a +#else +#define MYEMU(a) +#endif + +#define MYEMUDBG(a) MYEMU(MYDBG(a)) + +// Add Prefix (needed as workaround, same constant's names in different files causes conflict) +#define MY_ADD_PREFIX(prefix, var) prefix##_##var +#define MY_ADD_PREFIX2(prefix, var) MY_ADD_PREFIX(prefix, var) +#define MY_AP(var) MY_ADD_PREFIX2(MY_PREFIX, var) + +#define MY_VAR_TO_STR(var) #var +#define MY_VAR_TO_STR2(var) MY_VAR_TO_STR(var) +#define MY_CONST(var) (MY_VAR_TO_STR2(MY_PREFIX) "_" MY_VAR_TO_STR2(var)) + +#define CUDA_USE_TEXTURE +#define CUDA_USE_FLOAT4 + +//constants used by many classes + +//domain +#define _boxhi MY_AP(boxhi) +#define _boxlo MY_AP(boxlo) +#define _subhi MY_AP(subhi) +#define _sublo MY_AP(sublo) +#define _box_size MY_AP(box_size) +#define _prd MY_AP(prd) +#define _periodicity MY_AP(periodicity) +#define _triclinic MY_AP(triclinic) +#define _boxhi_lamda MY_AP(boxhi_lamda) +#define _boxlo_lamda MY_AP(boxlo_lamda) +#define _prd_lamda MY_AP(prd_lamda) +#define _h MY_AP(h) +#define _h_inv MY_AP(h_inv) +#define _h_rate MY_AP(h_rate) +__device__ __constant__ X_FLOAT _boxhi[3]; +__device__ __constant__ X_FLOAT _boxlo[3]; +__device__ __constant__ X_FLOAT _subhi[3]; +__device__ __constant__ X_FLOAT _sublo[3]; +__device__ __constant__ X_FLOAT _box_size[3]; +__device__ __constant__ X_FLOAT _prd[3]; +__device__ __constant__ int _periodicity[3]; +__device__ __constant__ int _triclinic; +__device__ __constant__ X_FLOAT _boxhi_lamda[3]; +__device__ __constant__ X_FLOAT _boxlo_lamda[3]; +__device__ __constant__ X_FLOAT _prd_lamda[3]; +__device__ __constant__ X_FLOAT _h[6]; +__device__ __constant__ X_FLOAT _h_inv[6]; +__device__ __constant__ V_FLOAT _h_rate[6]; + + +//atom properties +#define _x MY_AP(x) +#define _v MY_AP(v) +#define _f MY_AP(f) +#define _tag MY_AP(tag) +#define _type MY_AP(type) +#define _mask MY_AP(mask) +#define _image MY_AP(image) +#define _q MY_AP(q) +#define _mass MY_AP(mass) +#define _rmass MY_AP(rmass) +#define _rmass_flag MY_AP(rmass_flag) +#define _eatom MY_AP(eatom) +#define _vatom MY_AP(vatom) +#define _x_type MY_AP(x_type) +#define _radius MY_AP(radius) +#define _density MY_AP(density) +#define _omega MY_AP(omega) +#define _torque MY_AP(torque) +#define _special MY_AP(special) +#define _maxspecial MY_AP(maxspecial) +#define _nspecial MY_AP(nspecial) +#define _special_flag MY_AP(special_flag) +#define _molecule MY_AP(molecule) +#define _v_radius MY_AP(v_radius) +#define _omega_rmass MY_AP(omega_rmass) +#define _freeze_group_bit MY_AP(freeze_group_bit) +#define _map_array MY_AP(map_array) +__device__ __constant__ X_FLOAT* _x; //holds pointer to positions +__device__ __constant__ V_FLOAT* _v; +__device__ __constant__ F_FLOAT* _f; +__device__ __constant__ int* _tag; +__device__ __constant__ int* _type; +__device__ __constant__ int* _mask; +__device__ __constant__ int* _image; +__device__ __constant__ V_FLOAT* _mass; +__device__ __constant__ F_FLOAT* _q; +__device__ __constant__ V_FLOAT* _rmass; +__device__ __constant__ int _rmass_flag; +__device__ __constant__ ENERGY_FLOAT* _eatom; +__device__ __constant__ ENERGY_FLOAT* _vatom; +__device__ __constant__ X_FLOAT4* _x_type; //holds pointer to positions +__device__ __constant__ X_FLOAT* _radius; +__device__ __constant__ F_FLOAT* _density; +__device__ __constant__ V_FLOAT* _omega; +__device__ __constant__ F_FLOAT* _torque; +__device__ __constant__ int* _special; +__device__ __constant__ int _maxspecial; +__device__ __constant__ int* _nspecial; +__device__ __constant__ int _special_flag[4]; +__device__ __constant__ int* _molecule; +__device__ __constant__ V_FLOAT4* _v_radius; //holds pointer to positions +__device__ __constant__ V_FLOAT4* _omega_rmass; //holds pointer to positions +__device__ __constant__ int _freeze_group_bit; +__device__ __constant__ int* _map_array; + +#ifdef CUDA_USE_TEXTURE + + #define _x_tex MY_AP(x_tex) + #if X_PRECISION == 1 + texture _x_tex; + #else + texture _x_tex; + #endif + + #define _type_tex MY_AP(type_tex) + texture _type_tex; + + #define _x_type_tex MY_AP(x_type_tex) + #if X_PRECISION == 1 + texture _x_type_tex; + #else + texture _x_type_tex; + #endif + + #define _v_radius_tex MY_AP(v_radius_tex) + #if V_PRECISION == 1 + texture _v_radius_tex; + #else + texture _v_radius_tex; + #endif + + #define _omega_rmass_tex MY_AP(omega_rmass_tex) + #if V_PRECISION == 1 + texture _omega_rmass_tex; + #else + texture _omega_rmass_tex; + #endif + + #define _q_tex MY_AP(q_tex) + #if F_PRECISION == 1 + texture _q_tex; + #else + texture _q_tex; + #endif + +#endif + +//neighbor +#ifdef IncludeCommonNeigh +#define _inum MY_AP(inum) +#define _inum_border MY_AP(inum_border) +#define _ilist MY_AP(ilist) +#define _ilist_border MY_AP(ilist_border) +#define _numneigh MY_AP(numneigh) +#define _numneigh_border MY_AP(numneigh_border) +#define _numneigh_inner MY_AP(numneigh_inner) +#define _firstneigh MY_AP(firstneigh) +#define _neighbors MY_AP(neighbors) +#define _neighbors_border MY_AP(neighbors_border) +#define _neighbors_inner MY_AP(neighbors_inner) +#define _reneigh_flag MY_AP(reneigh_flag) +#define _triggerneighsq MY_AP(triggerneighsq) +#define _xhold MY_AP(xhold) +#define _maxhold MY_AP(maxhold) +#define _dist_check MY_AP(dist_check) +#define _neighbor_maxlocal MY_AP(neighbor_maxlocal) +#define _maxneighbors MY_AP(maxneighbors) +#define _overlap_comm MY_AP(overlap_comm) +__device__ __constant__ int _inum; +__device__ __constant__ int* _inum_border; +__device__ __constant__ int* _ilist; +__device__ __constant__ int* _ilist_border; +__device__ __constant__ int* _numneigh; +__device__ __constant__ int* _numneigh_border; +__device__ __constant__ int* _numneigh_inner; +__device__ __constant__ int** _firstneigh; +__device__ __constant__ int* _neighbors; +__device__ __constant__ int* _neighbors_border; +__device__ __constant__ int* _neighbors_inner; +__device__ __constant__ int* _reneigh_flag; +__device__ __constant__ X_FLOAT _triggerneighsq; +__device__ __constant__ X_FLOAT* _xhold; //holds pointer to positions +__device__ __constant__ int _maxhold; +__device__ __constant__ int _dist_check; +__device__ __constant__ int _neighbor_maxlocal; +__device__ __constant__ int _maxneighbors; +__device__ __constant__ int _overlap_comm; +#endif + +//system properties +#define _nall MY_AP(nall) +#define _nghost MY_AP(nghost) +#define _nlocal MY_AP(nlocal) +#define _nmax MY_AP(nmax) +#define _cuda_ntypes MY_AP(cuda_ntypes) +#define _dtf MY_AP(dtf) +#define _dtv MY_AP(dtv) +#define _factor MY_AP(factor) +#define _virial MY_AP(virial) +#define _eng_vdwl MY_AP(eng_vdwl) +#define _eng_coul MY_AP(eng_coul) +#define _molecular MY_AP(molecular) +__device__ __constant__ unsigned _nall; +__device__ __constant__ unsigned _nghost; +__device__ __constant__ unsigned _nlocal; +__device__ __constant__ unsigned _nmax; +__device__ __constant__ unsigned _cuda_ntypes; +__device__ __constant__ V_FLOAT _dtf; +__device__ __constant__ X_FLOAT _dtv; +__device__ __constant__ V_FLOAT _factor; +__device__ __constant__ ENERGY_FLOAT* _virial; +__device__ __constant__ ENERGY_FLOAT* _eng_vdwl; +__device__ __constant__ ENERGY_FLOAT* _eng_coul; +__device__ __constant__ int _molecular; + +//other general constants +#define _buffer MY_AP(buffer) +#define _flag MY_AP(flag) +#define _debugdata MY_AP(debugdata) +__device__ __constant__ void* _buffer; +__device__ __constant__ int* _flag; +__device__ __constant__ int* _debugdata; + +// pointers to data fields on GPU are hold in constant space +// -> reduces register usage and number of parameters for kernelcalls +// will be variables of file scope in cuda files + + + + +// maybe used to output cudaError_t +#define MY_OUTPUT_RESULT(result) \ + switch(result) \ + { \ + case cudaSuccess: printf(" => cudaSuccess\n"); break; \ + case cudaErrorInvalidValue: printf(" => cudaErrorInvalidValue\n"); break; \ + case cudaErrorInvalidSymbol: printf(" => cudaErrorInvalidSymbol\n"); break; \ + case cudaErrorInvalidDevicePointer: printf(" => cudaErrorInvalidDevicePointer\n"); break; \ + case cudaErrorInvalidMemcpyDirection: printf(" => cudaErrorInvalidMemcpyDirection\n"); break; \ + default: printf(" => unknown\n"); break; \ + } + +#ifdef _DEBUG +# define CUT_CHECK_ERROR(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + err = cudaThreadSynchronize(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + } +#else +# define CUT_CHECK_ERROR(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + } +#endif + +# define CUDA_SAFE_CALL_NO_SYNC( call) { \ + cudaError err = call; \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \ + __FILE__, __LINE__, cudaGetErrorString( err) ); \ + exit(EXIT_FAILURE); \ + } } + +# define CUDA_SAFE_CALL( call) CUDA_SAFE_CALL_NO_SYNC(call); + +#define X_MASK 1 +#define V_MASK 2 +#define F_MASK 4 +#define TAG_MASK 8 +#define TYPE_MASK 16 +#define MASK_MASK 32 +#define IMAGE_MASK 64 +#define Q_MASK 128 +#define MOLECULE_MASK 256 +#define RMASS_MASK 512 +#define RADIUS_MASK 1024 +#define DENSITY_MASK 2048 +#define OMEGA_MASK 4096 +#define TORQUE_MASK 8192 + + + +#endif // #ifdef _CUDA_COMMON_H_ From a053fd4788013f62f7e55245832218dad0a9ebc9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:35:39 +0000 Subject: [PATCH 206/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7143 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-CUDA/Install.sh | 20 +- src/USER-CUDA/comm_cuda.cpp | 4 + src/USER-CUDA/cuda.cpp | 3 + src/USER-CUDA/cuda_common.h | 344 ----------------------------- src/USER-CUDA/cuda_precision.h | 269 ----------------------- src/USER-CUDA/cuda_shared.h | 378 -------------------------------- src/USER-CUDA/neighbor_cuda.cpp | 7 +- src/USER-CUDA/verlet_cuda.cpp | 7 +- 8 files changed, 29 insertions(+), 1003 deletions(-) delete mode 100644 src/USER-CUDA/cuda_common.h delete mode 100644 src/USER-CUDA/cuda_precision.h delete mode 100644 src/USER-CUDA/cuda_shared.h diff --git a/src/USER-CUDA/Install.sh b/src/USER-CUDA/Install.sh index 3dc143471f..56f0dc80b9 100755 --- a/src/USER-CUDA/Install.sh +++ b/src/USER-CUDA/Install.sh @@ -82,6 +82,12 @@ if (test $1 = 1) then cp pair_eam_alloy_cuda.h .. cp pair_eam_cuda.h .. cp pair_eam_fs_cuda.h .. + cp pair_sw_cuda.h .. + cp pair_sw_cuda.cpp .. + cp pair_tersoff_cuda.h .. + cp pair_tersoff_cuda.cpp .. + cp pair_tersoff_zbl_cuda.h .. + cp pair_tersoff_zbl_cuda.cpp .. fi if (test -e ../pair_gran_hooke.cpp) then @@ -193,12 +199,9 @@ if (test $1 = 1) then cp verlet_cuda.h .. cp cuda.h .. - cp cuda_common.h .. cp cuda_data.h .. cp cuda_modify_flags.h .. cp cuda_neigh_list.h .. - cp cuda_precision.h .. - cp cuda_shared.h .. elif (test $1 = 0) then @@ -341,12 +344,15 @@ elif (test $1 = 0) then rm -f ../pppm_cuda.h rm -f ../verlet_cuda.h + rm -f ../pair_sw_cuda.h + rm -f ../pair_sw_cuda.cpp + rm -f ../pair_tersoff_cuda.h + rm -f ../pair_tersoff_cuda.cpp + rm -f ../pair_tersoff_zbl_cuda.h + rm -f ../pair_tersoff_zbl_cuda.cpp + rm -f ../cuda.h - rm -f ../cuda_common.h rm -f ../cuda_data.h rm -f ../cuda_modify_flags.h rm -f ../cuda_neigh_list.h - rm -f ../cuda_precision.h - rm -f ../cuda_shared.h - fi diff --git a/src/USER-CUDA/comm_cuda.cpp b/src/USER-CUDA/comm_cuda.cpp index 8e75f93ba5..ea4a4ee6a6 100644 --- a/src/USER-CUDA/comm_cuda.cpp +++ b/src/USER-CUDA/comm_cuda.cpp @@ -41,6 +41,9 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 #define BUFMIN 1000 #define BUFEXTRA 1000 + + + #define BIG 1.0e20 enum{SINGLE,MULTI}; @@ -137,6 +140,7 @@ void CommCuda::init() void CommCuda::setup() { + if(cuda->shared_data.pair.neighall) cutghostuser = MAX(2.0*neighbor->cutneighmax,cutghostuser); Comm::setup(); //upload changed geometry to device diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp index 39261bd7c0..819357bc16 100644 --- a/src/USER-CUDA/cuda.cpp +++ b/src/USER-CUDA/cuda.cpp @@ -46,6 +46,8 @@ using namespace LAMMPS_NS; + + Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp) { cuda_exists=true; @@ -309,6 +311,7 @@ void Cuda::setSharedDataZero() shared_data.pair.special_lj = 0; shared_data.pair.special_coul = 0; + shared_data.pair.neighall = false; shared_data.pppm.cudable_force = 0; diff --git a/src/USER-CUDA/cuda_common.h b/src/USER-CUDA/cuda_common.h deleted file mode 100644 index d4687ebd06..0000000000 --- a/src/USER-CUDA/cuda_common.h +++ /dev/null @@ -1,344 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - - Original Version: - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. - - ----------------------------------------------------------------------- - - USER-CUDA Package and associated modifications: - https://sourceforge.net/projects/lammpscuda/ - - Christian Trott, christian.trott@tu-ilmenau.de - Lars Winterfeld, lars.winterfeld@tu-ilmenau.de - Theoretical Physics II, University of Technology Ilmenau, Germany - - See the README file in the USER-CUDA directory. - - This software is distributed under the GNU General Public License. -------------------------------------------------------------------------- */ - -#ifndef _CUDA_COMMON_H_ -#define _CUDA_COMMON_H_ - -//#include "cutil.h" -#include "cuda_precision.h" -#include "cuda_wrapper_cu.h" - -#define CUDA_MAX_TYPES_PLUS_ONE 12 //for pair styles which use constant space for parameters, this needs to be one larger than the number of atom types -//this can not be arbitrarly large, since constant space is limited. -//in principle one could alter potentials to use global memory for parameters, some du that already since the first examples I encountered had a high number (20+) of atom types -//Christian -#define CUDA_MAX_TYPES2 (CUDA_MAX_TYPES_PLUS_ONE * CUDA_MAX_TYPES_PLUS_ONE) -#define CUDA_MAX_NSPECIAL 25 - -// define some easy-to-use debug and emulation macros -#ifdef _DEBUG -#define MYDBG(a) a -#else -#define MYDBG(a) -#endif - -#if __DEVICE_EMULATION__ -#define MYEMU(a) a -#else -#define MYEMU(a) -#endif - -#define MYEMUDBG(a) MYEMU(MYDBG(a)) - -// Add Prefix (needed as workaround, same constant's names in different files causes conflict) -#define MY_ADD_PREFIX(prefix, var) prefix##_##var -#define MY_ADD_PREFIX2(prefix, var) MY_ADD_PREFIX(prefix, var) -#define MY_AP(var) MY_ADD_PREFIX2(MY_PREFIX, var) - -#define MY_VAR_TO_STR(var) #var -#define MY_VAR_TO_STR2(var) MY_VAR_TO_STR(var) -#define MY_CONST(var) (MY_VAR_TO_STR2(MY_PREFIX) "_" MY_VAR_TO_STR2(var)) - -#define CUDA_USE_TEXTURE -#define CUDA_USE_FLOAT4 - -//constants used by many classes - -//domain -#define _boxhi MY_AP(boxhi) -#define _boxlo MY_AP(boxlo) -#define _subhi MY_AP(subhi) -#define _sublo MY_AP(sublo) -#define _box_size MY_AP(box_size) -#define _prd MY_AP(prd) -#define _periodicity MY_AP(periodicity) -#define _triclinic MY_AP(triclinic) -#define _boxhi_lamda MY_AP(boxhi_lamda) -#define _boxlo_lamda MY_AP(boxlo_lamda) -#define _prd_lamda MY_AP(prd_lamda) -#define _h MY_AP(h) -#define _h_inv MY_AP(h_inv) -#define _h_rate MY_AP(h_rate) -__device__ __constant__ X_FLOAT _boxhi[3]; -__device__ __constant__ X_FLOAT _boxlo[3]; -__device__ __constant__ X_FLOAT _subhi[3]; -__device__ __constant__ X_FLOAT _sublo[3]; -__device__ __constant__ X_FLOAT _box_size[3]; -__device__ __constant__ X_FLOAT _prd[3]; -__device__ __constant__ int _periodicity[3]; -__device__ __constant__ int _triclinic; -__device__ __constant__ X_FLOAT _boxhi_lamda[3]; -__device__ __constant__ X_FLOAT _boxlo_lamda[3]; -__device__ __constant__ X_FLOAT _prd_lamda[3]; -__device__ __constant__ X_FLOAT _h[6]; -__device__ __constant__ X_FLOAT _h_inv[6]; -__device__ __constant__ V_FLOAT _h_rate[6]; - - -//atom properties -#define _x MY_AP(x) -#define _v MY_AP(v) -#define _f MY_AP(f) -#define _tag MY_AP(tag) -#define _type MY_AP(type) -#define _mask MY_AP(mask) -#define _image MY_AP(image) -#define _q MY_AP(q) -#define _mass MY_AP(mass) -#define _rmass MY_AP(rmass) -#define _rmass_flag MY_AP(rmass_flag) -#define _eatom MY_AP(eatom) -#define _vatom MY_AP(vatom) -#define _x_type MY_AP(x_type) -#define _radius MY_AP(radius) -#define _density MY_AP(density) -#define _omega MY_AP(omega) -#define _torque MY_AP(torque) -#define _special MY_AP(special) -#define _maxspecial MY_AP(maxspecial) -#define _nspecial MY_AP(nspecial) -#define _special_flag MY_AP(special_flag) -#define _molecule MY_AP(molecule) -#define _v_radius MY_AP(v_radius) -#define _omega_rmass MY_AP(omega_rmass) -#define _freeze_group_bit MY_AP(freeze_group_bit) -#define _map_array MY_AP(map_array) -__device__ __constant__ X_FLOAT* _x; //holds pointer to positions -__device__ __constant__ V_FLOAT* _v; -__device__ __constant__ F_FLOAT* _f; -__device__ __constant__ int* _tag; -__device__ __constant__ int* _type; -__device__ __constant__ int* _mask; -__device__ __constant__ int* _image; -__device__ __constant__ V_FLOAT* _mass; -__device__ __constant__ F_FLOAT* _q; -__device__ __constant__ V_FLOAT* _rmass; -__device__ __constant__ int _rmass_flag; -__device__ __constant__ ENERGY_FLOAT* _eatom; -__device__ __constant__ ENERGY_FLOAT* _vatom; -__device__ __constant__ X_FLOAT4* _x_type; //holds pointer to positions -__device__ __constant__ X_FLOAT* _radius; -__device__ __constant__ F_FLOAT* _density; -__device__ __constant__ V_FLOAT* _omega; -__device__ __constant__ F_FLOAT* _torque; -__device__ __constant__ int* _special; -__device__ __constant__ int _maxspecial; -__device__ __constant__ int* _nspecial; -__device__ __constant__ int _special_flag[4]; -__device__ __constant__ int* _molecule; -__device__ __constant__ V_FLOAT4* _v_radius; //holds pointer to positions -__device__ __constant__ V_FLOAT4* _omega_rmass; //holds pointer to positions -__device__ __constant__ int _freeze_group_bit; -__device__ __constant__ int* _map_array; - -#ifdef CUDA_USE_TEXTURE - - #define _x_tex MY_AP(x_tex) - #if X_PRECISION == 1 - texture _x_tex; - #else - texture _x_tex; - #endif - - #define _type_tex MY_AP(type_tex) - texture _type_tex; - - #define _x_type_tex MY_AP(x_type_tex) - #if X_PRECISION == 1 - texture _x_type_tex; - #else - texture _x_type_tex; - #endif - - #define _v_radius_tex MY_AP(v_radius_tex) - #if V_PRECISION == 1 - texture _v_radius_tex; - #else - texture _v_radius_tex; - #endif - - #define _omega_rmass_tex MY_AP(omega_rmass_tex) - #if V_PRECISION == 1 - texture _omega_rmass_tex; - #else - texture _omega_rmass_tex; - #endif - - #define _q_tex MY_AP(q_tex) - #if F_PRECISION == 1 - texture _q_tex; - #else - texture _q_tex; - #endif - -#endif - -//neighbor -#ifdef IncludeCommonNeigh -#define _inum MY_AP(inum) -#define _inum_border MY_AP(inum_border) -#define _ilist MY_AP(ilist) -#define _ilist_border MY_AP(ilist_border) -#define _numneigh MY_AP(numneigh) -#define _numneigh_border MY_AP(numneigh_border) -#define _numneigh_inner MY_AP(numneigh_inner) -#define _firstneigh MY_AP(firstneigh) -#define _neighbors MY_AP(neighbors) -#define _neighbors_border MY_AP(neighbors_border) -#define _neighbors_inner MY_AP(neighbors_inner) -#define _reneigh_flag MY_AP(reneigh_flag) -#define _triggerneighsq MY_AP(triggerneighsq) -#define _xhold MY_AP(xhold) -#define _maxhold MY_AP(maxhold) -#define _dist_check MY_AP(dist_check) -#define _neighbor_maxlocal MY_AP(neighbor_maxlocal) -#define _maxneighbors MY_AP(maxneighbors) -#define _overlap_comm MY_AP(overlap_comm) -__device__ __constant__ int _inum; -__device__ __constant__ int* _inum_border; -__device__ __constant__ int* _ilist; -__device__ __constant__ int* _ilist_border; -__device__ __constant__ int* _numneigh; -__device__ __constant__ int* _numneigh_border; -__device__ __constant__ int* _numneigh_inner; -__device__ __constant__ int** _firstneigh; -__device__ __constant__ int* _neighbors; -__device__ __constant__ int* _neighbors_border; -__device__ __constant__ int* _neighbors_inner; -__device__ __constant__ int* _reneigh_flag; -__device__ __constant__ X_FLOAT _triggerneighsq; -__device__ __constant__ X_FLOAT* _xhold; //holds pointer to positions -__device__ __constant__ int _maxhold; -__device__ __constant__ int _dist_check; -__device__ __constant__ int _neighbor_maxlocal; -__device__ __constant__ int _maxneighbors; -__device__ __constant__ int _overlap_comm; -#endif - -//system properties -#define _nall MY_AP(nall) -#define _nghost MY_AP(nghost) -#define _nlocal MY_AP(nlocal) -#define _nmax MY_AP(nmax) -#define _cuda_ntypes MY_AP(cuda_ntypes) -#define _dtf MY_AP(dtf) -#define _dtv MY_AP(dtv) -#define _factor MY_AP(factor) -#define _virial MY_AP(virial) -#define _eng_vdwl MY_AP(eng_vdwl) -#define _eng_coul MY_AP(eng_coul) -#define _molecular MY_AP(molecular) -__device__ __constant__ unsigned _nall; -__device__ __constant__ unsigned _nghost; -__device__ __constant__ unsigned _nlocal; -__device__ __constant__ unsigned _nmax; -__device__ __constant__ unsigned _cuda_ntypes; -__device__ __constant__ V_FLOAT _dtf; -__device__ __constant__ X_FLOAT _dtv; -__device__ __constant__ V_FLOAT _factor; -__device__ __constant__ ENERGY_FLOAT* _virial; -__device__ __constant__ ENERGY_FLOAT* _eng_vdwl; -__device__ __constant__ ENERGY_FLOAT* _eng_coul; -__device__ __constant__ int _molecular; - -//other general constants -#define _buffer MY_AP(buffer) -#define _flag MY_AP(flag) -#define _debugdata MY_AP(debugdata) -__device__ __constant__ void* _buffer; -__device__ __constant__ int* _flag; -__device__ __constant__ int* _debugdata; - -// pointers to data fields on GPU are hold in constant space -// -> reduces register usage and number of parameters for kernelcalls -// will be variables of file scope in cuda files - - - - -// maybe used to output cudaError_t -#define MY_OUTPUT_RESULT(result) \ - switch(result) \ - { \ - case cudaSuccess: printf(" => cudaSuccess\n"); break; \ - case cudaErrorInvalidValue: printf(" => cudaErrorInvalidValue\n"); break; \ - case cudaErrorInvalidSymbol: printf(" => cudaErrorInvalidSymbol\n"); break; \ - case cudaErrorInvalidDevicePointer: printf(" => cudaErrorInvalidDevicePointer\n"); break; \ - case cudaErrorInvalidMemcpyDirection: printf(" => cudaErrorInvalidMemcpyDirection\n"); break; \ - default: printf(" => unknown\n"); break; \ - } - -#ifdef _DEBUG -# define CUT_CHECK_ERROR(errorMessage) { \ - cudaError_t err = cudaGetLastError(); \ - if( cudaSuccess != err) { \ - fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ - errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ - exit(EXIT_FAILURE); \ - } \ - err = cudaThreadSynchronize(); \ - if( cudaSuccess != err) { \ - fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ - errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ - exit(EXIT_FAILURE); \ - } \ - } -#else -# define CUT_CHECK_ERROR(errorMessage) { \ - cudaError_t err = cudaGetLastError(); \ - if( cudaSuccess != err) { \ - fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ - errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ - exit(EXIT_FAILURE); \ - } \ - } -#endif - -# define CUDA_SAFE_CALL_NO_SYNC( call) { \ - cudaError err = call; \ - if( cudaSuccess != err) { \ - fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \ - __FILE__, __LINE__, cudaGetErrorString( err) ); \ - exit(EXIT_FAILURE); \ - } } - -# define CUDA_SAFE_CALL( call) CUDA_SAFE_CALL_NO_SYNC(call); - -#define X_MASK 1 -#define V_MASK 2 -#define F_MASK 4 -#define TAG_MASK 8 -#define TYPE_MASK 16 -#define MASK_MASK 32 -#define IMAGE_MASK 64 -#define Q_MASK 128 -#define MOLECULE_MASK 256 -#define RMASS_MASK 512 -#define RADIUS_MASK 1024 -#define DENSITY_MASK 2048 -#define OMEGA_MASK 4096 -#define TORQUE_MASK 8192 - - - -#endif // #ifdef _CUDA_COMMON_H_ diff --git a/src/USER-CUDA/cuda_precision.h b/src/USER-CUDA/cuda_precision.h deleted file mode 100644 index 5b7d6a6843..0000000000 --- a/src/USER-CUDA/cuda_precision.h +++ /dev/null @@ -1,269 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - - Original Version: - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. - - ----------------------------------------------------------------------- - - USER-CUDA Package and associated modifications: - https://sourceforge.net/projects/lammpscuda/ - - Christian Trott, christian.trott@tu-ilmenau.de - Lars Winterfeld, lars.winterfeld@tu-ilmenau.de - Theoretical Physics II, University of Technology Ilmenau, Germany - - See the README file in the USER-CUDA directory. - - This software is distributed under the GNU General Public License. -------------------------------------------------------------------------- */ - -#ifndef CUDA_PRECISION_H_ -#define CUDA_PRECISION_H_ -/* This File gives Type definitions for mixed precision calculation in the cuda part of LAMMPS-CUDA. - * Predefined behaviour is given by global CUDA_PRECISION (can be overwritten during compilation). - * ***_FLOAT: type definition of given property - * ***_F: constant extension in code (1.0 is interpreted as double while 1.0f is interpreted as float, now use: 1.0CUDA_F) - */ - -#ifdef CUDA_USE_BINNING -#define CUDA_IF_BINNING(a) a -#else -#define CUDA_IF_BINNING(a) -#endif - -//GLOBAL - -#ifdef CUDA_PRECISION - #if CUDA_PRECISION == 1 - #define CUDA_FLOAT float - #define CUDA_F(x) x##f - #endif - #if CUDA_PRECISION == 2 - #define CUDA_FLOAT double - #define CUDA_F(x) x - #endif -#endif - -#ifndef CUDA_PRECISION - #define CUDA_FLOAT double - #define CUDA_F(x) x - #define CUDA_PRECISION 2 -#endif -//-------------------------------- -//-----------FFT----------------- -//-------------------------------- - -#ifdef FFT_PRECISION_CU - #if FFT_PRECISION_CU == 1 - #define FFT_FLOAT float - #define FFT_F(x) x##f - #endif - #if FFT_PRECISION_CU == 2 - #define FFT_FLOAT double - #define FFT_F(x) x - #endif -#endif - -#ifndef FFT_PRECISION_CU - #define FFT_FLOAT CUDA_FLOAT - #define FFT_F(x) CUDA_F(x) - #define FFT_PRECISION_CU CUDA_PRECISION -#endif - -//-------------------------------- -//-----------PPPM----------------- -//-------------------------------- - -#ifdef PPPM_PRECISION - #if PPPM_PRECISION == 1 - #define PPPM_FLOAT float - #define PPPM_F(x) x##f - #endif - #if PPPM_PRECISION == 2 - #define PPPM_FLOAT double - #define PPPM_F(x) x - #endif -#endif - -#ifndef PPPM_PRECISION - #define PPPM_FLOAT CUDA_FLOAT - #define PPPM_F(x) CUDA_F(x) - #define PPPM_PRECISION CUDA_PRECISION -#endif - -//-------------------------------- -//-----------FORCE----------------- -//-------------------------------- - - -#ifdef F_PRECISION - #if F_PRECISION == 1 - #define F_FLOAT float - #define F_F(x) x##f - #endif - #if F_PRECISION == 2 - #define F_FLOAT double - #define F_F(x) x - #endif -#endif - -#ifndef F_PRECISION - #define F_FLOAT CUDA_FLOAT - #define F_F(x) CUDA_F(x) - #define F_PRECISION CUDA_PRECISION -#endif - -#if F_PRECISION == 1 -#define _SQRT_ sqrtf -#define _RSQRT_ rsqrtf -#define _EXP_ expf -#else -#define _SQRT_ sqrt -#define _RSQRT_ rsqrt -#define _EXP_ exp -#endif - -#if F_PRECISION == 2 -struct F_FLOAT2 -{ - F_FLOAT x; - F_FLOAT y; -}; -struct F_FLOAT3 -{ - F_FLOAT x; - F_FLOAT y; - F_FLOAT z; -}; -struct F_FLOAT4 -{ - F_FLOAT x; - F_FLOAT y; - F_FLOAT z; - F_FLOAT w; -}; -#else -#define F_FLOAT2 float2 -#define F_FLOAT3 float3 -#define F_FLOAT4 float4 -#endif -//-------------------------------- -//-----------ENERGY----------------- -//-------------------------------- - -#ifndef ENERGY_PRECISION - #define ENERGY_FLOAT CUDA_FLOAT - #define ENERGY_F(x) CUDA_F(x) -#endif - -#ifdef ENERGY_PRECISION - #if ENERGY_PRECISION == 1 - #define ENERGY_FLOAT float - #define ENERGY_F(x) x##f - #endif - #if ENERGY_PRECISION == 2 - #define ENERGY_FLOAT double - #define ENERGY_F(x) x - #endif -#endif - -#ifndef ENERGY_PRECISION - #define ENERGY_FLOAT CUDA_FLOAT - #define ENERGY_F(x) CUDA_F(x) - #define ENERGY_PRECISION CUDA_PRECISION -#endif - -//-------------------------------- -//-----------POSITIONS------------ -//-------------------------------- - -#ifdef X_PRECISION - #if X_PRECISION == 1 - #define X_FLOAT float - #define X_F(x) x##f - #endif - #if X_PRECISION == 2 - #define X_FLOAT double - #define X_F(x) x - #endif -#endif - -#ifndef X_PRECISION - #define X_FLOAT CUDA_FLOAT - #define X_F(x) CUDA_F(x) - #define X_PRECISION CUDA_PRECISION -#endif - -#if X_PRECISION == 2 -struct X_FLOAT2 -{ - X_FLOAT x; - X_FLOAT y; -}; -struct X_FLOAT3 -{ - X_FLOAT x; - X_FLOAT y; - X_FLOAT z; -}; -struct X_FLOAT4 -{ - X_FLOAT x; - X_FLOAT y; - X_FLOAT z; - X_FLOAT w; -}; -#else -#define X_FLOAT2 float2 -#define X_FLOAT3 float3 -#define X_FLOAT4 float4 -#endif - -//-------------------------------- -//-----------velocities----------- -//-------------------------------- - -#ifdef V_PRECISION - #if V_PRECISION == 1 - #define V_FLOAT float - #define V_F(x) x##f - #endif - #if V_PRECISION == 2 - #define V_FLOAT double - #define V_F(x) x - #endif -#endif - -#ifndef V_PRECISION - #define V_FLOAT CUDA_FLOAT - #define V_F(x) CUDA_F(x) - #define V_PRECISION CUDA_PRECISION -#endif - -#if V_PRECISION == 2 -struct V_FLOAT4 -{ - V_FLOAT x; - V_FLOAT y; - V_FLOAT z; - V_FLOAT w; -}; -#else -#define V_FLOAT4 float4 -#endif - -#ifdef NO_PREC_TIMING -struct timespec_2 -{ - unsigned int tv_sec; - unsigned int tv_nsec; -}; - -#define timespec timespec_2 -#define clock_gettime(a,b) -#endif -#endif /*CUDA_PRECISION_H_*/ diff --git a/src/USER-CUDA/cuda_shared.h b/src/USER-CUDA/cuda_shared.h deleted file mode 100644 index f7983fff05..0000000000 --- a/src/USER-CUDA/cuda_shared.h +++ /dev/null @@ -1,378 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - - Original Version: - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. - - ----------------------------------------------------------------------- - - USER-CUDA Package and associated modifications: - https://sourceforge.net/projects/lammpscuda/ - - Christian Trott, christian.trott@tu-ilmenau.de - Lars Winterfeld, lars.winterfeld@tu-ilmenau.de - Theoretical Physics II, University of Technology Ilmenau, Germany - - See the README file in the USER-CUDA directory. - - This software is distributed under the GNU General Public License. -------------------------------------------------------------------------- */ - -#ifndef _CUDA_SHARED_H_ -#define _CUDA_SHARED_H_ -#include "cuda_precision.h" - -#define CUDA_MAX_DEBUG_SIZE 1000 //size of debugdata array (allows for so many doubles or twice as many int) - -struct dev_array -{ - void* dev_data; // pointer to memory address on cuda device - unsigned dim[3]; // array dimensions -}; - -struct cuda_shared_atom // relevent data from atom class -{ - dev_array dx; // cumulated distance for binning settings - dev_array x; // position - dev_array v; // velocity - dev_array f; // force - dev_array tag; - dev_array type; // global ID number, there are ghosttype = ntypes (ntypescuda=ntypes+1) - dev_array mask; - dev_array image; - dev_array q; // charges - dev_array mass; // per-type masses - dev_array rmass; // per-atom masses - dev_array radius; // per-atom radius - dev_array density; - dev_array omega; - dev_array torque; - dev_array molecule; - - dev_array special; - int maxspecial; - dev_array nspecial; - int* special_flag; - int molecular; - - dev_array eatom; // per-atom energy - dev_array vatom; // per-atom virial - int need_eatom; - int need_vatom; - - dev_array x_type; // position + type in X_FLOAT4 struct - dev_array v_radius; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style - dev_array omega_rmass; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style - - double* mass_host; // remember per-type host pointer to masses - //int natoms; // total # of atoms in system, could be 0 - int nghost; // and ghost atoms on this proc - int nlocal; // # of owned - int nall; // total # of atoms in this proc - int nmax; // max # of owned+ghost in arrays on this proc - int ntypes; - int q_flag; // do we have charges? - int rmass_flag; // do we have per-atom masses? - int firstgroup; - int nfirst; - - int update_nlocal; - int update_nmax; - - dev_array xhold; // position at last neighboring - X_FLOAT triggerneighsq; // maximum square movement before reneighboring - int reneigh_flag; // is reneighboring necessary - int maxhold; // size of xhold - int dist_check; //perform distance check for reneighboring - dev_array binned_id; //id of each binned atom (not tag!!) - dev_array binned_idnew; //new id of each binned atom for sorting basically setting atom[binned_id[k]] at atom[binned_newid[k]] - float bin_extraspace; - int bin_dim[3]; - int bin_nmax; - dev_array map_array; -}; - -struct cuda_shared_pair // relevent data from pair class -{ - char cudable_force; // check for (cudable_force!=0) - X_FLOAT cut_global; - X_FLOAT cut_inner_global; - X_FLOAT cut_coul_global; - double** cut; // type-type cutoff - double** cutsq; // type-type cutoff - double** cut_inner; // type-type cutoff for coul - double** cut_coul; // type-type cutoff for coul - double** coeff1; // tpye-type pair parameters - double** coeff2; - double** coeff3; - double** coeff4; - double** coeff5; - double** coeff6; - double** coeff7; - double** coeff8; - double** coeff9; - double** coeff10; - double** offset; - double* special_lj; - double* special_coul; - dev_array virial; // ENERGY_FLOAT - dev_array eng_vdwl; // ENERGY_FLOAT - dev_array eng_coul; // ENERGY_FLOAT - X_FLOAT cut_coulsq_global; - F_FLOAT g_ewald,kappa; - int freeze_group_bit; - - dev_array coeff1_gm; - dev_array coeff2_gm; - dev_array coeff3_gm; - dev_array coeff4_gm; - dev_array coeff5_gm; - dev_array coeff6_gm; - dev_array coeff7_gm; - dev_array coeff8_gm; - dev_array coeff9_gm; - dev_array coeff10_gm; - - int lastgridsize; - int n_energy_virial; - int collect_forces_later; - int use_block_per_atom; - int override_block_per_atom; - -}; - -struct cuda_shared_domain // relevent data from domain class -{ - X_FLOAT sublo[3]; // orthogonal box -> sub-box bounds on this proc - X_FLOAT subhi[3]; - X_FLOAT boxlo[3]; - X_FLOAT boxhi[3]; - X_FLOAT prd[3]; - int periodicity[3]; // xyz periodicity as array - - int triclinic; - X_FLOAT xy; - X_FLOAT xz; - X_FLOAT yz; - X_FLOAT boxlo_lamda[3]; - X_FLOAT boxhi_lamda[3]; - X_FLOAT prd_lamda[3]; - X_FLOAT h[6]; - X_FLOAT h_inv[6]; - V_FLOAT h_rate[6]; - int update; -}; - -struct cuda_shared_pppm -{ - char cudable_force; -#ifdef FFT_CUFFT - FFT_FLOAT* work1; - FFT_FLOAT* work2; - FFT_FLOAT* work3; - PPPM_FLOAT* greensfn; - PPPM_FLOAT* fkx; - PPPM_FLOAT* fky; - PPPM_FLOAT* fkz; - PPPM_FLOAT* vg; -#endif - int* part2grid; - PPPM_FLOAT* density_brick; - int* density_brick_int; - PPPM_FLOAT density_intScale; - PPPM_FLOAT* vdx_brick; - PPPM_FLOAT* vdy_brick; - PPPM_FLOAT* vdz_brick; - PPPM_FLOAT* density_fft; - ENERGY_FLOAT* energy; - ENERGY_FLOAT* virial; - int nxlo_in; - int nxhi_in; - int nxlo_out; - int nxhi_out; - int nylo_in; - int nyhi_in; - int nylo_out; - int nyhi_out; - int nzlo_in; - int nzhi_in; - int nzlo_out; - int nzhi_out; - int nx_pppm; - int ny_pppm; - int nz_pppm; - PPPM_FLOAT qqrd2e; - int order; - // float3 sublo; - PPPM_FLOAT* rho_coeff; - int nmax; - int nlocal; - PPPM_FLOAT* debugdata; - PPPM_FLOAT delxinv; - PPPM_FLOAT delyinv; - PPPM_FLOAT delzinv; - int nlower; - int nupper; - PPPM_FLOAT shiftone; - -}; - -struct cuda_shared_comm -{ - int maxswap; - int maxlistlength; - dev_array pbc; - dev_array slablo; - dev_array slabhi; - dev_array multilo; - dev_array multihi; - dev_array sendlist; - int grow_flag; - int comm_phase; - - int nsend; - int* nsend_swap; - int* send_size; - int* recv_size; - double** buf_send; - void** buf_send_dev; - double** buf_recv; - void** buf_recv_dev; - void* buffer; - int buffer_size; - double overlap_split_ratio; -}; - -struct cuda_shared_neighlist // member of CudaNeighList, has no instance in cuda_shared_data -{ - int maxlocal; - int inum; // # of I atoms neighbors are stored for local indices of I atoms - int inum_border2; - dev_array inum_border; // # of atoms which interact with border atoms - dev_array ilist; - dev_array ilist_border; - dev_array numneigh; - dev_array numneigh_inner; - dev_array numneigh_border; - dev_array firstneigh; - dev_array neighbors; - dev_array neighbors_border; - dev_array neighbors_inner; - int maxpage; - dev_array page_pointers; - dev_array* pages; - int maxneighbors; - int neigh_lists_per_page; - double** cutneighsq; - CUDA_FLOAT* cu_cutneighsq; - int* binned_id; - int* bin_dim; - int bin_nmax; - float bin_extraspace; - double maxcut; - dev_array ex_type; - int nex_type; - dev_array ex1_bit; - dev_array ex2_bit; - int nex_group; - dev_array ex_mol_bit; - int nex_mol; - -}; - -struct cuda_compile_settings // this is used to compare compile settings (i.e. precision) of the cu files, and the cpp files -{ - int prec_glob; - int prec_x; - int prec_v; - int prec_f; - int prec_pppm; - int prec_fft; - int cufft; - int arch; -}; - -struct cuda_timings_struct -{ - //Debug: - double test1; - double test2; - //transfers - double transfer_upload_tmp_constr; - double transfer_download_tmp_deconstr; - - //communication - double comm_forward_total; - double comm_forward_mpi_upper; - double comm_forward_mpi_lower; - double comm_forward_kernel_pack; - double comm_forward_kernel_unpack; - double comm_forward_kernel_self; - double comm_forward_upload; - double comm_forward_download; - - double comm_exchange_total; - double comm_exchange_mpi; - double comm_exchange_kernel_pack; - double comm_exchange_kernel_unpack; - double comm_exchange_kernel_fill; - double comm_exchange_cpu_pack; - double comm_exchange_upload; - double comm_exchange_download; - - double comm_border_total; - double comm_border_mpi; - double comm_border_kernel_pack; - double comm_border_kernel_unpack; - double comm_border_kernel_self; - double comm_border_kernel_buildlist; - double comm_border_upload; - double comm_border_download; - - //pair forces - double pair_xtype_conversion; - double pair_kernel; - double pair_virial; - double pair_force_collection; - - //neighbor - double neigh_bin; - double neigh_build; - double neigh_special; - - //PPPM - double pppm_particle_map; - double pppm_make_rho; - double pppm_brick2fft; - double pppm_poisson; - double pppm_fillbrick; - double pppm_fieldforce; - double pppm_compute; - -}; - -struct cuda_shared_data // holds space for all relevent data from the different classes -{ - void* buffer; //holds temporary GPU data [data used in subroutines, which has not to be consistend outside of that routine] - int buffersize; //maxsize of buffer - int buffer_new; //should be 1 if the pointer to buffer has changed - void* flag; - void* debugdata; //array for easily collecting debugdata from device class cuda contains the corresponding cu_debugdata and host array - cuda_shared_atom atom; - cuda_shared_pair pair; - cuda_shared_domain domain; - cuda_shared_pppm pppm; - cuda_shared_comm comm; - cuda_compile_settings compile_settings; - cuda_timings_struct cuda_timings; - int exchange_dim; - int me; //mpi rank - unsigned int datamask; - int overlap_comm; -}; - - -#endif // #ifndef _CUDA_SHARED_H_ diff --git a/src/USER-CUDA/neighbor_cuda.cpp b/src/USER-CUDA/neighbor_cuda.cpp index 99bf2dce3c..dc5af9f2f8 100644 --- a/src/USER-CUDA/neighbor_cuda.cpp +++ b/src/USER-CUDA/neighbor_cuda.cpp @@ -26,6 +26,9 @@ using namespace LAMMPS_NS; + + + enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ @@ -56,9 +59,9 @@ void NeighborCuda::choose_build(int index, NeighRequest *rq) { Neighbor::choose_build(index,rq); - if (rq->full && style == NSQ && rq->ghost == 0 && rq->cudable) + if (rq->full && style == NSQ && rq->cudable) pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_nsq_cuda; - else if (rq->full && style == BIN && rq->ghost == 0 && rq->cudable) + else if (rq->full && style == BIN && rq->cudable) pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_bin_cuda; } diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp index 0c3f675fae..fbaa1800a5 100644 --- a/src/USER-CUDA/verlet_cuda.cpp +++ b/src/USER-CUDA/verlet_cuda.cpp @@ -21,6 +21,7 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ + #include #include #include @@ -56,6 +57,7 @@ using namespace LAMMPS_NS; #define MAKETIMEING + VerletCuda::VerletCuda(LAMMPS *lmp, int narg, char **arg) : Verlet(lmp, narg, arg) { cuda = lmp->cuda; if(cuda == NULL) @@ -132,20 +134,19 @@ void VerletCuda::setup() cuda->uploadAll(); neighbor->build(); neighbor->ncalls = 0; - cuda->uploadAllNeighborLists(); + if(atom->mass) cuda->cu_mass->upload(); if(cuda->cu_map_array) cuda->cu_map_array->upload(); - + // compute all forces ev_set(update->ntimestep); if(elist_atom) cuda->shared_data.atom.need_eatom = 1; if(vlist_atom) cuda->shared_data.atom.need_vatom = 1; if(elist_atom||vlist_atom) cuda->checkResize(); - int test_BpA_vs_TpA = true; timespec starttime; From 6cebfc12b5c904dc7f03659a3a1fdb52a145cd41 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:36:25 +0000 Subject: [PATCH 207/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7144 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-CUDA/pair_sw_cuda.cpp | 209 ++++++++++++++++++++++ src/USER-CUDA/pair_sw_cuda.h | 66 +++++++ src/USER-CUDA/pair_tersoff_cuda.cpp | 206 ++++++++++++++++++++++ src/USER-CUDA/pair_tersoff_cuda.h | 66 +++++++ src/USER-CUDA/pair_tersoff_zbl_cuda.cpp | 220 ++++++++++++++++++++++++ src/USER-CUDA/pair_tersoff_zbl_cuda.h | 53 ++++++ 6 files changed, 820 insertions(+) create mode 100644 src/USER-CUDA/pair_sw_cuda.cpp create mode 100644 src/USER-CUDA/pair_sw_cuda.h create mode 100644 src/USER-CUDA/pair_tersoff_cuda.cpp create mode 100644 src/USER-CUDA/pair_tersoff_cuda.h create mode 100644 src/USER-CUDA/pair_tersoff_zbl_cuda.cpp create mode 100644 src/USER-CUDA/pair_tersoff_zbl_cuda.h diff --git a/src/USER-CUDA/pair_sw_cuda.cpp b/src/USER-CUDA/pair_sw_cuda.cpp new file mode 100644 index 0000000000..601ad7f2cf --- /dev/null +++ b/src/USER-CUDA/pair_sw_cuda.cpp @@ -0,0 +1,209 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_sw_cuda.h" +#include "cuda_data.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "cuda_neigh_list.h" +#include "update.h" +#include "integrate.h" +#include "respa.h" +#include "memory.h" +#include "error.h" +#include "cuda.h" + +using namespace LAMMPS_NS; + + + + +/* ---------------------------------------------------------------------- */ + +PairSWCuda::PairSWCuda(LAMMPS *lmp) : PairSW(lmp) +{ + cuda = lmp->cuda; + if(cuda == NULL) + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + + allocated2 = false; + params_f = NULL; + cuda->setSystemParams(); + cuda->shared_data.pair.cudable_force = 1; + cuda->shared_data.pair.override_block_per_atom = 0; + cuda->shared_data.pair.neighall = true; + init = false; +} + +/* ---------------------------------------------------------------------- + remember pointer to arrays in cuda shared data +------------------------------------------------------------------------- */ + +void PairSWCuda::allocate() +{ + if(! allocated) PairSW::allocate(); + if(! allocated2) + { + allocated2 = true; + cuda->shared_data.pair.cutsq = cutsq; + cuda->shared_data.pair.special_lj = force->special_lj; + cuda->shared_data.pair.special_coul = force->special_coul; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::compute(int eflag, int vflag) +{ + if(!init) {Cuda_PairSWCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements); init=true;} + if (eflag || vflag) ev_setup(eflag,vflag); + if(eflag) cuda->cu_eng_vdwl->upload(); + if(vflag) cuda->cu_virial->upload(); + + Cuda_PairSWCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map + if(not cuda->shared_data.pair.collect_forces_later) + { + if(eflag) cuda->cu_eng_vdwl->download(); + if(vflag) cuda->cu_virial->download(); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::settings(int narg, char **arg) +{ + PairSW::settings(narg, arg); +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::coeff(int narg, char **arg) +{ + PairSW::coeff(narg, arg); + allocate(); + params_f = (ParamSW_Float *) memory->srealloc(params_f,maxparam*sizeof(ParamSW_Float), + "pair:params_f"); + for(int i=0;ishared_data.pair.cut_global = cutmax; +} + +void PairSWCuda::init_style() +{ + MYDBG(printf("# CUDA PairSWCuda::init_style start\n"); ) + + int irequest; + + irequest = neighbor->request(this); + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->cudable = 1; + neighbor->requests[irequest]->ghost = 1; + + + MYDBG(printf("# CUDA PairSWCuda::init_style end\n"); ) +} + +void PairSWCuda::init_list(int id, NeighList *ptr) +{ + MYDBG(printf("# CUDA PairSWCuda::init_list\n");) + PairSW::init_list(id, ptr); + // right now we can only handle verlet (id 0), not respa + if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr); + // see Neighbor::init() for details on lammps lists' logic + MYDBG(printf("# CUDA PairSWCuda::init_list end\n");) + cu_params_f = (ParamSW_Float*) CudaWrapper_AllocCudaData(sizeof(ParamSW_Float)*maxparam); + CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(ParamSW_Float)*maxparam); + cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements); + cu_elem2param->upload(); + cu_map = new cCudaData ( map,atom->ntypes+1 ); + cu_map->upload(); +} + +void PairSWCuda::ev_setup(int eflag, int vflag) +{ + int maxeatomold=maxeatom; + PairSW::ev_setup(eflag,vflag); + + if (eflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );} + + if (vflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );} +} + + diff --git a/src/USER-CUDA/pair_sw_cuda.h b/src/USER-CUDA/pair_sw_cuda.h new file mode 100644 index 0000000000..be9ba9bb3d --- /dev/null +++ b/src/USER-CUDA/pair_sw_cuda.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(sw/cuda,PairSWCuda) + +#else + +#ifndef PAIR_SW_CUDA_H +#define PAIR_SW_CUDA_H + +#include "pair_sw_cuda_cu.h" +#include "pair_sw.h" +#include "cuda_data.h" + +namespace LAMMPS_NS { + +class PairSWCuda : public PairSW +{ + public: + PairSWCuda(class LAMMPS *); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_list(int, class NeighList *); + void init_style(); + void ev_setup(int eflag, int vflag); + protected: + + class Cuda *cuda; + void allocate(); + bool allocated2; + class CudaNeighList* cuda_neigh_list; + ParamSW_Float* params_f; + ParamSW_Float* cu_params_f; + cCudaData* cu_elem2param; + cCudaData* cu_map; + bool init; + bool iszbl; +}; + +} + +#endif +#endif diff --git a/src/USER-CUDA/pair_tersoff_cuda.cpp b/src/USER-CUDA/pair_tersoff_cuda.cpp new file mode 100644 index 0000000000..4f1dba4e31 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_cuda.cpp @@ -0,0 +1,206 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_tersoff_cuda.h" +#include "cuda_data.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "cuda_neigh_list.h" +#include "update.h" +#include "integrate.h" +#include "respa.h" +#include "memory.h" +#include "error.h" +#include "cuda.h" + +using namespace LAMMPS_NS; + + + + +/* ---------------------------------------------------------------------- */ + +PairTersoffCuda::PairTersoffCuda(LAMMPS *lmp) : PairTersoff(lmp) +{ + cuda = lmp->cuda; + if(cuda == NULL) + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + + allocated2 = false; + params_f = NULL; + cuda->setSystemParams(); + cuda->shared_data.pair.cudable_force = 1; + cuda->shared_data.pair.override_block_per_atom = 0; + cuda->shared_data.pair.neighall = true; + init = false; + iszbl = false; +} + +/* ---------------------------------------------------------------------- + remember pointer to arrays in cuda shared data +------------------------------------------------------------------------- */ + +void PairTersoffCuda::allocate() +{ + if(! allocated) PairTersoff::allocate(); + if(! allocated2) + { + allocated2 = true; + cuda->shared_data.pair.cutsq = cutsq; + cuda->shared_data.pair.special_lj = force->special_lj; + cuda->shared_data.pair.special_coul = force->special_coul; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::compute(int eflag, int vflag) +{ + if(!init) {Cuda_PairTersoffCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements,iszbl); init=true;} + if (eflag || vflag) ev_setup(eflag,vflag); + if(eflag) cuda->cu_eng_vdwl->upload(); + if(vflag) cuda->cu_virial->upload(); + + Cuda_PairTersoffCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map + if(not cuda->shared_data.pair.collect_forces_later) + { + if(eflag) cuda->cu_eng_vdwl->download(); + if(vflag) cuda->cu_virial->download(); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::settings(int narg, char **arg) +{ + PairTersoff::settings(narg, arg); +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::coeff(int narg, char **arg) +{ + PairTersoff::coeff(narg, arg); + allocate(); + params_f = (Param_Float *) memory->srealloc(params_f,maxparam*sizeof(Param_Float), + "pair:params_f"); + for(int i=0;ishared_data.pair.cut_global = cutmax; +} + +void PairTersoffCuda::init_style() +{ + MYDBG(printf("# CUDA PairTersoffCuda::init_style start\n"); ) + + int irequest; + + irequest = neighbor->request(this); + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->cudable = 1; + neighbor->requests[irequest]->ghost = 1; + + + MYDBG(printf("# CUDA PairTersoffCuda::init_style end\n"); ) +} + +void PairTersoffCuda::init_list(int id, NeighList *ptr) +{ + MYDBG(printf("# CUDA PairTersoffCuda::init_list\n");) + PairTersoff::init_list(id, ptr); + // right now we can only handle verlet (id 0), not respa + if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr); + // see Neighbor::init() for details on lammps lists' logic + MYDBG(printf("# CUDA PairTersoffCuda::init_list end\n");) + cu_params_f = (Param_Float*) CudaWrapper_AllocCudaData(sizeof(Param_Float)*maxparam); + CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(Param_Float)*maxparam); + cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements); + cu_elem2param->upload(); + cu_map = new cCudaData ( map,atom->ntypes+1 ); + cu_map->upload(); +} + +void PairTersoffCuda::ev_setup(int eflag, int vflag) +{ + int maxeatomold=maxeatom; + PairTersoff::ev_setup(eflag,vflag); + + if (eflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );} + + if (vflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );} +} + + diff --git a/src/USER-CUDA/pair_tersoff_cuda.h b/src/USER-CUDA/pair_tersoff_cuda.h new file mode 100644 index 0000000000..34a06f91a9 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_cuda.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tersoff/cuda,PairTersoffCuda) + +#else + +#ifndef PAIR_TERSOFF_CUDA_H +#define PAIR_TERSOFF_CUDA_H + +#include "pair_tersoff_cuda_cu.h" +#include "pair_tersoff.h" +#include "cuda_data.h" + +namespace LAMMPS_NS { + +class PairTersoffCuda : public PairTersoff +{ + public: + PairTersoffCuda(class LAMMPS *); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_list(int, class NeighList *); + void init_style(); + void ev_setup(int eflag, int vflag); + protected: + + class Cuda *cuda; + void allocate(); + bool allocated2; + class CudaNeighList* cuda_neigh_list; + Param_Float* params_f; + Param_Float* cu_params_f; + cCudaData* cu_elem2param; + cCudaData* cu_map; + bool init; + bool iszbl; +}; + +} + +#endif +#endif diff --git a/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp new file mode 100644 index 0000000000..45236da515 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp @@ -0,0 +1,220 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Aidan Thompson (SNL) - original Tersoff implementation + David Farrell (NWU) - ZBL addition +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_tersoff_zbl_cuda.h" +#include "atom.h" +#include "update.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "force.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define MAXLINE 1024 +#define DELTA 4 + +/* ---------------------------------------------------------------------- */ + +PairTersoffZBLCuda::PairTersoffZBLCuda(LAMMPS *lmp) : PairTersoffCuda(lmp) +{ + // hard-wired constants in metal or real units + // a0 = Bohr radius + // epsilon0 = permittivity of vacuum = q / energy-distance units + // e = unit charge + // 1 Kcal/mole = 0.043365121 eV + + if (strcmp(update->unit_style,"metal") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635; + global_e = 1.0; + } else if (strcmp(update->unit_style,"real") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635 * 0.043365121; + global_e = 1.0; + } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units"); + iszbl = true; +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffZBLCuda::read_file(char *file) +{ + int params_per_line = 21; + char **words = new char*[params_per_line+1]; + + delete [] params; + params = NULL; + nparams = 0; + + // open file on proc 0 + + FILE *fp; + if (comm->me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open Tersoff potential file %s",file); + error->one(FLERR,str); + } + } + + // read each line out of file, skipping blank lines or leading '#' + // store line of params if all 3 element tags are in element list + + int n,nwords,ielement,jelement,kelement; + char line[MAXLINE],*ptr; + int eof = 0; + + while (1) { + if (comm->me == 0) { + ptr = fgets(line,MAXLINE,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + // strip comment, skip line if blank + + if (ptr = strchr(line,'#')) *ptr = '\0'; + nwords = atom->count_words(line); + if (nwords == 0) continue; + + // concatenate additional lines until have params_per_line words + + while (nwords < params_per_line) { + n = strlen(line); + if (comm->me == 0) { + ptr = fgets(&line[n],MAXLINE-n,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + if (ptr = strchr(line,'#')) *ptr = '\0'; + nwords = atom->count_words(line); + } + + if (nwords != params_per_line) + error->all(FLERR,"Incorrect format in Tersoff potential file"); + + // words = ptrs to all words in line + + nwords = 0; + words[nwords++] = strtok(line," \t\n\r\f"); + while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue; + + // ielement,jelement,kelement = 1st args + // if all 3 args are in element list, then parse this line + // else skip to next line + + for (ielement = 0; ielement < nelements; ielement++) + if (strcmp(words[0],elements[ielement]) == 0) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (strcmp(words[1],elements[jelement]) == 0) break; + if (jelement == nelements) continue; + for (kelement = 0; kelement < nelements; kelement++) + if (strcmp(words[2],elements[kelement]) == 0) break; + if (kelement == nelements) continue; + + // load up parameter settings and error check their values + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), + "pair:params"); + } + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].kelement = kelement; + params[nparams].powerm = atof(words[3]); + params[nparams].gamma = atof(words[4]); + params[nparams].lam3 = atof(words[5]); + params[nparams].c = atof(words[6]); + params[nparams].d = atof(words[7]); + params[nparams].h = atof(words[8]); + params[nparams].powern = atof(words[9]); + params[nparams].beta = atof(words[10]); + params[nparams].lam2 = atof(words[11]); + params[nparams].bigb = atof(words[12]); + params[nparams].bigr = atof(words[13]); + params[nparams].bigd = atof(words[14]); + params[nparams].lam1 = atof(words[15]); + params[nparams].biga = atof(words[16]); + params[nparams].Z_i = atof(words[17]); + params[nparams].Z_j = atof(words[18]); + params[nparams].ZBLcut = atof(words[19]); + params[nparams].ZBLexpscale = atof(words[20]); + + // currently only allow m exponent of 1 or 3 + + params[nparams].powermint = int(params[nparams].powerm); + + if ( + params[nparams].lam3 < 0.0 || params[nparams].c < 0.0 || + params[nparams].d < 0.0 || params[nparams].powern < 0.0 || + params[nparams].beta < 0.0 || params[nparams].lam2 < 0.0 || + params[nparams].bigb < 0.0 || params[nparams].bigr < 0.0 || + params[nparams].bigd < 0.0 || + params[nparams].bigd > params[nparams].bigr || + params[nparams].lam3 < 0.0 || params[nparams].biga < 0.0 || + params[nparams].powerm - params[nparams].powermint != 0.0 || + (params[nparams].powermint != 3 && params[nparams].powermint != 1) || + params[nparams].gamma < 0.0 || + params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 || + params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0) + error->all(FLERR,"Illegal Tersoff parameter"); + + nparams++; + } + + delete [] words; +} + +void PairTersoffZBLCuda::coeff(int narg, char **arg) +{ + PairTersoffCuda::coeff(narg, arg); + for(int i=0;i Date: Thu, 20 Oct 2011 14:56:21 +0000 Subject: [PATCH 208/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7145 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/Install.sh | 8 ++ src/ASPHERE/compute_erotate_asphere.cpp | 92 ++++++++++---- src/ASPHERE/compute_erotate_asphere.h | 4 +- src/ASPHERE/fix_nve_line.cpp | 162 ++++++++++++++++++++++++ src/ASPHERE/fix_nve_line.h | 44 +++++++ src/ASPHERE/fix_nve_tri.cpp | 156 +++++++++++++++++++++++ src/ASPHERE/fix_nve_tri.h | 44 +++++++ 7 files changed, 487 insertions(+), 23 deletions(-) create mode 100644 src/ASPHERE/fix_nve_line.cpp create mode 100644 src/ASPHERE/fix_nve_line.h create mode 100644 src/ASPHERE/fix_nve_tri.cpp create mode 100644 src/ASPHERE/fix_nve_tri.h diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index a494ae63d7..c896a5c285 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -8,6 +8,8 @@ if (test $1 = 1) then cp fix_nph_asphere.cpp .. cp fix_npt_asphere.cpp .. cp fix_nve_asphere.cpp .. + cp fix_nve_line.cpp .. + cp fix_nve_tri.cpp .. cp fix_nvt_asphere.cpp .. cp pair_gayberne.cpp .. cp pair_resquared.cpp .. @@ -18,6 +20,8 @@ if (test $1 = 1) then cp fix_nph_asphere.h .. cp fix_npt_asphere.h .. cp fix_nve_asphere.h .. + cp fix_nve_line.h .. + cp fix_nve_tri.h .. cp fix_nvt_asphere.h .. cp pair_gayberne.h .. cp pair_resquared.h .. @@ -30,6 +34,8 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.cpp rm -f ../fix_npt_asphere.cpp rm -f ../fix_nve_asphere.cpp + rm -f ../fix_nve_line.cpp + rm -f ../fix_nve_tri.cpp rm -f ../fix_nvt_asphere.cpp rm -f ../pair_gayberne.cpp rm -f ../pair_resquared.cpp @@ -40,6 +46,8 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.h rm -f ../fix_npt_asphere.h rm -f ../fix_nve_asphere.h + rm -f ../fix_nve_line.h + rm -f ../fix_nve_tri.h rm -f ../fix_nvt_asphere.h rm -f ../pair_gayberne.h rm -f ../pair_resquared.h diff --git a/src/ASPHERE/compute_erotate_asphere.cpp b/src/ASPHERE/compute_erotate_asphere.cpp index 80c4083a9f..a18b62c1f1 100644 --- a/src/ASPHERE/compute_erotate_asphere.cpp +++ b/src/ASPHERE/compute_erotate_asphere.cpp @@ -16,6 +16,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "update.h" #include "force.h" #include "memory.h" @@ -36,9 +38,12 @@ ComputeERotateAsphere(LAMMPS *lmp, int narg, char **arg) : // error check - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) - error->all(FLERR,"Compute erotate/asphere requires atom style ellipsoid"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_ellipsoid && !avec_line && !avec_tri) + error->all(FLERR,"Compute erotate/asphere requires " + "atom style ellipsoid or line or tri"); } /* ---------------------------------------------------------------------- */ @@ -49,13 +54,21 @@ void ComputeERotateAsphere::init() // no point particles allowed, spherical is OK int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *mask = atom->mask; int nlocal = atom->nlocal; + int flag; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - if (ellipsoid[i] < 0) + if (mask[i] & groupbit) { + flag = 0; + if (ellipsoid && ellipsoid[i] >= 0) flag = 1; + if (line && line[i] >= 0) flag = 1; + if (tri && tri[i] >= 0) flag = 1; + if (!flag) error->one(FLERR,"Compute erotate/asphere requires extended particles"); + } pfactor = 0.5 * force->mvv2e; } @@ -66,8 +79,16 @@ double ComputeERotateAsphere::compute_scalar() { invoked_scalar = update->ntimestep; - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *ebonus; + if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; + double **omega = atom->omega; double **angmom = atom->angmom; double *rmass = atom->rmass; int *mask = atom->mask; @@ -76,6 +97,7 @@ double ComputeERotateAsphere::compute_scalar() // sum rotational energy for each particle // no point particles since divide by inertia + double length; double *shape,*quat; double wbody[3],inertia[3]; double rot[3][3]; @@ -83,28 +105,54 @@ double ComputeERotateAsphere::compute_scalar() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { + if (ellipsoid && ellipsoid[i] >= 0) { + shape = ebonus[ellipsoid[i]].shape; + quat = ebonus[ellipsoid[i]].quat; - shape = bonus[ellipsoid[i]].shape; - quat = bonus[ellipsoid[i]].quat; + // principal moments of inertia + + inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0; + inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0; + inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0; + + // wbody = angular velocity in body frame + + MathExtra::quat_to_mat(quat,rot); + MathExtra::transpose_matvec(rot,angmom[i],wbody); + wbody[0] /= inertia[0]; + wbody[1] /= inertia[1]; + wbody[2] /= inertia[2]; + + erotate += inertia[0]*wbody[0]*wbody[0] + + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; - // principal moments of inertia + } else if (line && line[i] >= 0) { + length = lbonus[line[i]].length; - inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0; - inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0; - inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0; + erotate += (omega[i][0]*omega[i][0] + omega[i][1]*omega[i][1] + + omega[i][2]*omega[i][2]) * length*length*rmass[i] / 12.0; - // wbody = angular velocity in body frame + } else if (tri && tri[i] >= 0) { - MathExtra::quat_to_mat(quat,rot); - MathExtra::transpose_matvec(rot,angmom[i],wbody); - wbody[0] /= inertia[0]; - wbody[1] /= inertia[1]; - wbody[2] /= inertia[2]; - - erotate += inertia[0]*wbody[0]*wbody[0] + - inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; + // principal moments of inertia + + inertia[0] = tbonus[tri[i]].inertia[0]; + inertia[1] = tbonus[tri[i]].inertia[1]; + inertia[2] = tbonus[tri[i]].inertia[2]; + + // wbody = angular velocity in body frame + + MathExtra::quat_to_mat(tbonus[tri[i]].quat,rot); + MathExtra::transpose_matvec(rot,angmom[i],wbody); + wbody[0] /= inertia[0]; + wbody[1] /= inertia[1]; + wbody[2] /= inertia[2]; + + erotate += inertia[0]*wbody[0]*wbody[0] + + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; + } } - + MPI_Allreduce(&erotate,&scalar,1,MPI_DOUBLE,MPI_SUM,world); scalar *= pfactor; return scalar; diff --git a/src/ASPHERE/compute_erotate_asphere.h b/src/ASPHERE/compute_erotate_asphere.h index 0e3ae271d7..9274425795 100644 --- a/src/ASPHERE/compute_erotate_asphere.h +++ b/src/ASPHERE/compute_erotate_asphere.h @@ -32,7 +32,9 @@ class ComputeERotateAsphere : public Compute { private: double pfactor; - class AtomVecEllipsoid *avec; + class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; }; } diff --git a/src/ASPHERE/fix_nve_line.cpp b/src/ASPHERE/fix_nve_line.cpp new file mode 100644 index 0000000000..682119c6a1 --- /dev/null +++ b/src/ASPHERE/fix_nve_line.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "fix_nve_line.h" +#include "atom.h" +#include "atom_vec_line.h" +#include "domain.h" +#include "math_const.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define INERTIA (1.0/12.0) // moment of inertia prefactor for line segment + +/* ---------------------------------------------------------------------- */ + +FixNVELine::FixNVELine(LAMMPS *lmp, int narg, char **arg) : + FixNVE(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Illegal fix nve/line command"); + + time_integrate = 1; + + MINUSPI = -MY_PI; + TWOPI = 2.0*MY_PI; + + // error checks + + avec = (AtomVecLine *) atom->style_match("line"); + if (!avec) error->all(FLERR,"Fix nve/line requires atom style line"); +} + +/* ---------------------------------------------------------------------- */ + +int FixNVELine::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + mask |= INITIAL_INTEGRATE_RESPA; + mask |= FINAL_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::init() +{ + int i,itype; + + if (domain->dimension != 2) + error->all(FLERR,"Fix nve/line can only be used for 2d simulations"); + + // check that all particles are line segments + // no point particles allowed + + int *line = atom->line; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (line[i] < 0) error->one(FLERR,"Fix nve/line requires line particles"); + } + + FixNVE::init(); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::initial_integrate(int vflag) +{ + double dtfm,dtirotate,delx,dely,length,theta; + + AtomVecLine::Bonus *bonus = avec->bonus; + int *line = atom->line; + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + double dtfrotate = dtf / INERTIA; + + // update v,x,omega,theta for all particles + // d_omega/dt = torque / inertia + // bound theta by -PI to PI + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + + length = bonus[line[i]].length; + theta = bonus[line[i]].theta; + dtirotate = dtfrotate / (length*length*rmass[i]); + omega[i][2] += dtirotate * torque[i][2]; + theta += dtv * omega[i][2]; + while (theta <= MINUSPI) theta += TWOPI; + while (theta > MY_PI) theta -= TWOPI; + bonus[line[i]].theta = theta; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::final_integrate() +{ + double dtfm,dtirotate,length; + + AtomVecLine::Bonus *bonus = avec->bonus; + int *line = atom->line; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + double dtfrotate = dtf / INERTIA; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + + length = bonus[line[i]].length; + dtirotate = dtfrotate / (length*length*rmass[i]); + omega[i][2] += dtirotate * torque[i][2]; + } +} diff --git a/src/ASPHERE/fix_nve_line.h b/src/ASPHERE/fix_nve_line.h new file mode 100644 index 0000000000..7d6e962044 --- /dev/null +++ b/src/ASPHERE/fix_nve_line.h @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(nve/line,FixNVELine) + +#else + +#ifndef LMP_FIX_NVE_LINE_H +#define LMP_FIX_NVE_LINE_H + +#include "fix_nve.h" + +namespace LAMMPS_NS { + +class FixNVELine : public FixNVE { + public: + FixNVELine(class LAMMPS *, int, char **); + ~FixNVELine() {} + int setmask(); + void init(); + void initial_integrate(int); + void final_integrate(); + + private: + double MINUSPI,TWOPI; + class AtomVecLine *avec; +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/fix_nve_tri.cpp b/src/ASPHERE/fix_nve_tri.cpp new file mode 100644 index 0000000000..ca83afcdbb --- /dev/null +++ b/src/ASPHERE/fix_nve_tri.cpp @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "fix_nve_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_tri.h" +#include "domain.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixNVETri::FixNVETri(LAMMPS *lmp, int narg, char **arg) : + FixNVE(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Illegal fix nve/tri command"); + + time_integrate = 1; + + // error checks + + avec = (AtomVecTri *) atom->style_match("tri"); + if (!avec) error->all(FLERR,"Fix nve/tri requires atom style tri"); +} + +/* ---------------------------------------------------------------------- */ + +int FixNVETri::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + mask |= INITIAL_INTEGRATE_RESPA; + mask |= FINAL_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::init() +{ + int i,itype; + + if (domain->dimension != 3) + error->all(FLERR,"Fix nve/line can only be used for 3d simulations"); + + // check that all particles are triangles + // no point particles allowed + + int *tri = atom->tri; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (tri[i] < 0) error->one(FLERR,"Fix nve/tri requires tri particles"); + } + + FixNVE::init(); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::initial_integrate(int vflag) +{ + double dtfm; + double omega[3]; + + AtomVecTri::Bonus *bonus = avec->bonus; + int *tri = atom->tri; + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **angmom = atom->angmom; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + dtq = 0.5 * dtv; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + x[i][2] += dtv * v[i][2]; + + // update angular momentum by 1/2 step + + angmom[i][0] += dtf * torque[i][0]; + angmom[i][1] += dtf * torque[i][1]; + angmom[i][2] += dtf * torque[i][2]; + + // compute omega at 1/2 step from angmom at 1/2 step and current q + // update quaternion a full step via Richardson iteration + // returns new normalized quaternion + + MathExtra::mq_to_omega(angmom[i],bonus[tri[i]].quat, + bonus[tri[i]].inertia,omega); + MathExtra::richardson(bonus[tri[i]].quat,angmom[i],omega, + bonus[tri[i]].inertia,dtq); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::final_integrate() +{ + double dtfm; + + double **v = atom->v; + double **f = atom->f; + double **angmom = atom->angmom; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + + angmom[i][0] += dtf * torque[i][0]; + angmom[i][1] += dtf * torque[i][1]; + angmom[i][2] += dtf * torque[i][2]; + } +} diff --git a/src/ASPHERE/fix_nve_tri.h b/src/ASPHERE/fix_nve_tri.h new file mode 100644 index 0000000000..e268b6b1e6 --- /dev/null +++ b/src/ASPHERE/fix_nve_tri.h @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(nve/tri,FixNVETri) + +#else + +#ifndef LMP_FIX_NVE_TRI_H +#define LMP_FIX_NVE_TRI_H + +#include "fix_nve.h" + +namespace LAMMPS_NS { + +class FixNVETri : public FixNVE { + public: + FixNVETri(class LAMMPS *, int, char **); + ~FixNVETri() {} + int setmask(); + void init(); + void initial_integrate(int); + void final_integrate(); + + private: + double dtq; + class AtomVecTri *avec; +}; + +} + +#endif +#endif From ca8dfd3d7c07ac0560cfe8230e705cc068fa1716 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:56:49 +0000 Subject: [PATCH 209/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7146 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SRD/fix_srd.cpp | 1164 +++++++++++++++++++++++---------- src/SRD/fix_srd.h | 52 +- src/atom.cpp | 12 +- src/atom.h | 4 +- src/compute_property_atom.cpp | 428 +++++++++++- src/compute_property_atom.h | 19 +- src/fix_rigid.cpp | 325 ++++++--- src/fix_rigid.h | 11 +- src/read_data.cpp | 99 ++- src/read_data.h | 6 +- src/set.cpp | 136 +++- 11 files changed, 1688 insertions(+), 568 deletions(-) diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index 411beb9c9d..b673b9b7b5 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -22,6 +22,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "group.h" #include "update.h" #include "force.h" @@ -42,7 +44,7 @@ using namespace LAMMPS_NS; using namespace MathConst; enum{SLIP,NOSLIP}; -enum{SPHERE,ELLIPSOID,WALL}; +enum{SPHERE,ELLIPSOID,LINE,TRIANGLE,WALL}; enum{INSIDE_ERROR,INSIDE_WARN,INSIDE_IGNORE}; enum{BIG_MOVE,SRD_MOVE,SRD_ROTATE}; enum{CUBIC_ERROR,CUBIC_WARN}; @@ -50,10 +52,13 @@ enum{SHIFT_NO,SHIFT_YES,SHIFT_POSSIBLE}; enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp -#define INERTIA 0.4 -#define ATOMPERBIN 10 +#define EINERTIA 0.2 // moment of inertia prefactor for ellipsoid + +#define ATOMPERBIN 30 #define BIG 1.0e20 #define VBINSIZE 5 +#define TOLERANCE 0.00001 +#define MAXITER 20 //#define SRD_DEBUG 1 //#define SRD_DEBUG_ATOMID 58 @@ -95,7 +100,7 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) cubictol = 0.01; shiftuser = SHIFT_NO; shiftseed = 0; - streamflag = 1; + tstat = 0; int iarg = 8; while (iarg < narg) { @@ -156,10 +161,10 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) else error->all(FLERR,"Illegal fix srd command"); shiftseed = atoi(arg[iarg+2]); iarg += 3; - } else if (strcmp(arg[iarg],"stream") == 0) { + } else if (strcmp(arg[iarg],"tstat") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); - if (strcmp(arg[iarg+1],"yes") == 0) streamflag = 1; - else if (strcmp(arg[iarg+1],"no") == 0) streamflag = 0; + if (strcmp(arg[iarg+1],"no") == 0) tstat = 0; + else if (strcmp(arg[iarg+1],"yes") == 0) tstat = 1; else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else error->all(FLERR,"Illegal fix srd command"); @@ -168,7 +173,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) // error check if (nevery <= 0) error->all(FLERR,"Illegal fix srd command"); - if (bigexist && biggroup < 0) error->all(FLERR,"Could not find fix srd group ID"); + if (bigexist && biggroup < 0) + error->all(FLERR,"Could not find fix srd group ID"); if (gridsrd <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (temperature_srd <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (seed <= 0) error->all(FLERR,"Illegal fix srd command"); @@ -176,7 +182,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (maxbounceallow < 0) error->all(FLERR,"Illegal fix srd command"); if (lamdaflag && lamda <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (gridsearch <= 0.0) error->all(FLERR,"Illegal fix srd command"); - if (cubictol < 0.0 || cubictol > 1.0) error->all(FLERR,"Illegal fix srd command"); + if (cubictol < 0.0 || cubictol > 1.0) + error->all(FLERR,"Illegal fix srd command"); if ((shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE) && shiftseed <= 0) error->all(FLERR,"Illegal fix srd command"); @@ -236,6 +243,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) // atom style pointers to particles that store bonus info avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); // fix parameters @@ -289,7 +298,8 @@ void FixSRD::init() { // error checks - if (force->newton_pair == 0) error->all(FLERR,"Fix srd requires newton pair on"); + if (force->newton_pair == 0) + error->all(FLERR,"Fix srd requires newton pair on"); if (bigexist && comm->ghost_velocity == 0) error->all(FLERR,"Fix srd requires ghost atoms store velocity"); if (bigexist && collidestyle == NOSLIP && !atom->torque_flag) @@ -319,19 +329,21 @@ void FixSRD::init() fwall = wallfix->fwall; walltrigger = 0.5 * neighbor->skin; if (wallfix->overlap && overlap == 0 && me == 0) - error->warning(FLERR,"Fix SRD walls overlap but fix srd overlap not set"); + error->warning(FLERR, + "Fix SRD walls overlap but fix srd overlap not set"); } } // set change_flags if box size or shape changes - change_size = change_shape = 0; + change_size = change_shape = deformflag = 0; if (domain->nonperiodic == 2) change_size = 1; for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->box_change) { if (modify->fix[i]->box_change_size) change_size = 1; if (modify->fix[i]->box_change_shape) change_shape = 1; if (strcmp(modify->fix[i]->style,"deform") == 0) { + deformflag = 1; FixDeform *deform = (FixDeform *) modify->fix[i]; if (deform->box_change_shape && deform->remapflag != V_REMAP) error->all(FLERR,"Using fix srd with inconsistent " @@ -339,6 +351,10 @@ void FixSRD::init() } } + if (deformflag && tstat == 0 && me == 0) + error->warning(FLERR, + "Using fix srd with box deformation but no SRD thermostat"); + // parameterize based on current box volume dimension = domain->dimension; @@ -391,7 +407,8 @@ void FixSRD::setup(int vflag) setup_bounds(); if (dist_srd_reneigh < nevery*dt_big*vmax && me == 0) - error->warning(FLERR,"Fix srd SRD moves may trigger frequent reneighboring"); + error->warning(FLERR, + "Fix srd SRD moves may trigger frequent reneighboring"); // setup search bins and search stencil based on these distances @@ -407,6 +424,7 @@ void FixSRD::setup(int vflag) reneighflag = BIG_MOVE; pre_neighbor(); } + /* ---------------------------------------------------------------------- assign SRD particles to bins assign big particles to all bins they overlap @@ -416,6 +434,7 @@ void FixSRD::pre_neighbor() { int i,j,m,ix,iy,iz,jx,jy,jz,ibin,jbin,lo,hi; double rsq,cutbinsq; + double xlamda[3]; // grow SRD per-atom bin arrays if necessary @@ -561,7 +580,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-xblo2)*bininv2x); if (hi < 0) continue; - if (hi >= nbin2x) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2x) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-xblo2)*bininv2x); @@ -583,7 +603,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-yblo2)*bininv2y); if (hi < 0) continue; - if (hi >= nbin2y) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2y) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-yblo2)*bininv2y); @@ -605,7 +626,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-zblo2)*bininv2z); if (hi < 0) continue; - if (hi >= nbin2z) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2z) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-zblo2)*bininv2z); @@ -645,6 +667,7 @@ void FixSRD::pre_neighbor() void FixSRD::post_force(int vflag) { int i,m,ix,iy,iz; + double xlamda[3]; // zero per-timestep stats @@ -765,19 +788,20 @@ void FixSRD::post_force(int vflag) /* ---------------------------------------------------------------------- reset SRD velocities - may perform random shifting by 1/2 bin in each dimension + may perform random shifting by up to 1/2 bin in each dimension called at pre-neighbor stage when all SRDs are now inside my sub-domain - for triclinic, will set mean velocity to box deformation velocity + if tstat, then thermostat SRD particles as well, including streaming effects ------------------------------------------------------------------------- */ void FixSRD::reset_velocities() { int i,j,n,ix,iy,iz,ibin,axis,sign,irandom; - double u[3],vave[3]; - double vx,vy,vz,vsq; - double *vold,*vnew,*xlamda; + double u[3],vsum[3]; + double vx,vy,vz,vsq,tbin,scale; + double *vave,*vnew,*xlamda; + double vstream[3]; - // if requested, perform a dynamic shift + // if requested, perform a dynamic shift of bin positions if (shiftflag) { double *boxlo; @@ -831,39 +855,23 @@ void FixSRD::reset_velocities() if (triclinic) domain->lamda2x(nlocal); - if (triclinic && streamflag) { - double *h_rate = domain->h_rate; - double *h_ratelo = domain->h_ratelo; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - xlamda = x[i]; - v[i][0] -= h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + - h_rate[4]*xlamda[2] + h_ratelo[0]; - v[i][1] -= h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; - v[i][2] -= h_rate[2]*xlamda[2] + h_ratelo[2]; - } - } - // for each bin I have particles contributing to: - // compute ave v and v^2 of particles in that bin + // compute summed v of particles in that bin // if I own the bin, set its random value, else set to 0.0 for (i = 0; i < nbins; i++) { n = 0; - vave[0] = vave[1] = vave[2] = 0.0; + vsum[0] = vsum[1] = vsum[2] = 0.0; for (j = binhead[i]; j >= 0; j = binnext[j]) { - vx = v[j][0]; - vy = v[j][1]; - vz = v[j][2]; - vave[0] += vx; - vave[1] += vy; - vave[2] += vz; + vsum[0] += v[j][0]; + vsum[1] += v[j][1]; + vsum[2] += v[j][2]; n++; } - vbin[i].vave[0] = vave[0]; - vbin[i].vave[1] = vave[1]; - vbin[i].vave[2] = vave[2]; + vbin[i].vsum[0] = vsum[0]; + vbin[i].vsum[1] = vsum[1]; + vbin[i].vsum[2] = vsum[2]; vbin[i].n = n; if (vbin[i].owner) vbin[i].random = random->uniform(); else vbin[i].random = 0.0; @@ -874,24 +882,43 @@ void FixSRD::reset_velocities() if (shifts[shiftflag].commflag) vbin_comm(shiftflag); // for each bin I have particles contributing to: - // reassign particle velocity by rotation around a random axis - // accumulate T_srd for each bin I own - // for triclinic, replace mean velocity with stream velocity + // compute vave over particles in bin + // thermal velocity of each particle = v - vave + // rotate thermal vel of each particle around one of 6 random axes + // add vave back to each particle + // thermostat if requested: + // if no deformation, rescale thermal vel to temperature + // if deformation, rescale thermal vel and change vave to vstream + // these are settings for extra dof_temp, dof_tstat to subtract + // (not sure why these settings work best) + // no deformation, no tstat: dof_temp = 1 + // yes deformation, no tstat: doesn't matter, system will not equilibrate + // no deformation, yes tstat: dof_temp = dof_tstat = 1 + // yes deformation, yes tstat: dof_temp = dof_tstat = 0 + // accumulate final T_srd for each bin I own + + double tfactor = force->mvv2e * mass_srd / (dimension * force->boltz); + int dof_temp = 1; + int dof_tstat; + if (tstat) { + if (deformflag) dof_tstat = dof_temp = 0; + else dof_tstat = 1; + } srd_bin_temp = 0.0; srd_bin_count = 0; if (dimension == 2) axis = 2; + double *h_rate = domain->h_rate; + double *h_ratelo = domain->h_ratelo; for (i = 0; i < nbins; i++) { n = vbin[i].n; if (n == 0) continue; - vold = vbin[i].vave; - vold[0] /= n; - vold[1] /= n; - vold[2] /= n; - - vnew = vold; + vave = vbin[i].vsum; + vave[0] /= n; + vave[1] /= n; + vave[2] /= n; irandom = static_cast (6.0*vbin[i].random); sign = irandom % 2; @@ -900,47 +927,63 @@ void FixSRD::reset_velocities() vsq = 0.0; for (j = binhead[i]; j >= 0; j = binnext[j]) { if (axis == 0) { - u[0] = v[j][0]-vold[0]; - u[1] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2]; - u[2] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1]; + u[0] = v[j][0]-vave[0]; + u[1] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2]; + u[2] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1]; } else if (axis == 1) { - u[1] = v[j][1]-vold[1]; - u[0] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2]; - u[2] = sign ? vold[0]-v[j][0] : v[j][0]-vold[0]; + u[1] = v[j][1]-vave[1]; + u[0] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2]; + u[2] = sign ? vave[0]-v[j][0] : v[j][0]-vave[0]; } else { - u[2] = v[j][2]-vold[2]; - u[1] = sign ? v[j][0]-vold[0] : vold[0]-v[j][0]; - u[0] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1]; + u[2] = v[j][2]-vave[2]; + u[1] = sign ? v[j][0]-vave[0] : vave[0]-v[j][0]; + u[0] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1]; } vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; - v[j][0] = u[0] + vnew[0]; - v[j][1] = u[1] + vnew[1]; - v[j][2] = u[2] + vnew[2]; + v[j][0] = u[0] + vave[0]; + v[j][1] = u[1] + vave[1]; + v[j][2] = u[2] + vave[2]; + } + + if (tstat && n > 1) { + if (deformflag) { + xlamda = vbin[i].xctr; + vstream[0] = h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + + h_rate[4]*xlamda[2] + h_ratelo[0]; + vstream[1] = h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; + vstream[2] = h_rate[2]*xlamda[2] + h_ratelo[2]; + } else { + vstream[0] = vave[0]; + vstream[1] = vave[1]; + vstream[2] = vave[2]; + } + + // tbin = thermal temperature of particles in bin + // scale = scale factor for thermal velocity + + tbin = vsq/(n-dof_tstat) * tfactor; + scale = sqrt(temperature_srd/tbin); + + vsq = 0.0; + for (j = binhead[i]; j >= 0; j = binnext[j]) { + u[0] = (v[j][0] - vave[0]) * scale; + u[1] = (v[j][1] - vave[1]) * scale; + u[2] = (v[j][2] - vave[2]) * scale; + vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; + v[j][0] = u[0] + vstream[0]; + v[j][1] = u[1] + vstream[1]; + v[j][2] = u[2] + vstream[2]; + } } // sum partial contribution of my particles to T even if I don't own bin - // but only count bin if I own it, so that bin is counted exactly once + // but only count bin if I own it, so each bin is counted exactly once - if (n > 1) { - srd_bin_temp += vsq / (n-1); - if (vbin[i].owner) srd_bin_count++; - } + if (n > 1) srd_bin_temp += vsq/(n-dof_temp); + if (vbin[i].owner) srd_bin_count++; } - srd_bin_temp *= force->mvv2e * mass_srd / (dimension * force->boltz); - - if (triclinic && streamflag) { - double *h_rate = domain->h_rate; - double *h_ratelo = domain->h_ratelo; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - xlamda = x[i]; - v[i][0] += h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + - h_rate[4]*xlamda[2] + h_ratelo[0]; - v[i][1] += h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; - v[i][2] += h_rate[2]*xlamda[2] + h_ratelo[2]; - } - } + srd_bin_temp *= tfactor; // rescale any too-large velocities @@ -1032,9 +1075,9 @@ void FixSRD::vbin_pack(BinAve *vbin, int n, int *list, double *buf) for (int i = 0; i < n; i++) { j = list[i]; buf[m++] = vbin[j].n; - buf[m++] = vbin[j].vave[0]; - buf[m++] = vbin[j].vave[1]; - buf[m++] = vbin[j].vave[2]; + buf[m++] = vbin[j].vsum[0]; + buf[m++] = vbin[j].vsum[1]; + buf[m++] = vbin[j].vsum[2]; buf[m++] = vbin[j].random; } } @@ -1050,9 +1093,9 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list) for (int i = 0; i < n; i++) { j = list[i]; vbin[j].n += static_cast (buf[m++]); - vbin[j].vave[0] += buf[m++]; - vbin[j].vave[1] += buf[m++]; - vbin[j].vave[2] += buf[m++]; + vbin[j].vsum[0] += buf[m++]; + vbin[j].vsum[1] += buf[m++]; + vbin[j].vsum[2] += buf[m++]; vbin[j].random += buf[m++]; } } @@ -1065,7 +1108,7 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list) void FixSRD::collisions_single() { - int i,j,k,m,type,mbig,ibin,ibounce,inside,collide_flag; + int i,j,k,m,type,nbig,ibin,ibounce,inside,collide_flag,lineside; double dt,t_remain; double norm[3],xscoll[3],xbcoll[3],vsnew[3]; Big *big; @@ -1097,11 +1140,11 @@ void FixSRD::collisions_single() dt = dt_big; while (collide_flag) { - mbig = nbinbig[ibin]; - if (ibounce == 0) ncheck += mbig; + nbig = nbinbig[ibin]; + if (ibounce == 0) ncheck += nbig; collide_flag = 0; - for (m = 0; m < mbig; m++) { + for (m = 0; m < nbig; m++) { k = binbig[ibin][m]; big = &biglist[k]; j = big->index; @@ -1161,17 +1204,11 @@ void FixSRD::collisions_single() } if (collidestyle == SLIP) { - if (type == SPHERE) - slip_sphere(v[i],v[j],norm,vsnew); - else if (type == ELLIPSOID) - slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - slip_wall(v[i],j,norm,vsnew); + if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew); + else slip_wall(v[i],j,norm,vsnew); } else { - if (type != WALL) - noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - noslip_wall(v[i],j,xscoll,norm,vsnew); + if (type != WALL) noslip(v[i],v[j],x[j],big,-1, xscoll,norm,vsnew); + else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew); } if (dimension == 2) vsnew[2] = 0.0; @@ -1222,7 +1259,7 @@ void FixSRD::collisions_single() void FixSRD::collisions_multi() { - int i,j,k,m,type,mbig,ibin,ibounce,inside,jfirst,typefirst; + int i,j,k,m,type,nbig,ibin,ibounce,inside,jfirst,typefirst,jlast; double dt,t_remain,t_first; double norm[3],xscoll[3],xbcoll[3],vsnew[3]; double normfirst[3],xscollfirst[3],xbcollfirst[3]; @@ -1251,22 +1288,31 @@ void FixSRD::collisions_multi() if (nbinbig[ibin] == 0) continue; ibounce = 0; + jlast = -1; dt = dt_big; while (1) { - mbig = nbinbig[ibin]; - if (ibounce == 0) ncheck += mbig; + nbig = nbinbig[ibin]; + if (ibounce == 0) ncheck += nbig; t_first = 0.0; - for (m = 0; m < mbig; m++) { + for (m = 0; m < nbig; m++) { k = binbig[ibin][m]; big = &biglist[k]; j = big->index; + if (j == jlast) continue; type = big->type; - if (type == SPHERE) inside = inside_sphere(x[i],x[j],big); - else if (type == ELLIPSOID) inside = inside_ellipsoid(x[i],x[j],big); - else inside = inside_wall(x[i],j); + if (type == SPHERE) + inside = inside_sphere(x[i],x[j],big); + else if (type == ELLIPSOID) + inside = inside_ellipsoid(x[i],x[j],big); + else if (type == LINE) + inside = inside_line(x[i],x[j],v[i],v[j],big,dt); + else if (type == TRIANGLE) + inside = inside_tri(x[i],x[j],v[i],v[j],big,dt); + else + inside = inside_wall(x[i],j); if (inside) { if (type == SPHERE) @@ -1275,6 +1321,12 @@ void FixSRD::collisions_multi() else if (type == ELLIPSOID) t_remain = collision_ellipsoid_exact(x[i],x[j],v[i],v[j],big, xscoll,xbcoll,norm); + else if (type == LINE) + t_remain = collision_line_exact(x[i],x[j],v[i],v[j],big,dt, + xscoll,xbcoll,norm); + else if (type == TRIANGLE) + t_remain = collision_tri_exact(x[i],x[j],v[i],v[j],big,dt, + xscoll,xbcoll,norm); else t_remain = collision_wall_exact(x[i],j,v[i],xscoll,xbcoll,norm); @@ -1318,7 +1370,7 @@ void FixSRD::collisions_multi() } if (t_first == 0.0) break; - j = jfirst; + j = jlast = jfirst; type = typefirst; xscoll[0] = xscollfirst[0]; xscoll[1] = xscollfirst[1]; @@ -1331,17 +1383,11 @@ void FixSRD::collisions_multi() norm[2] = normfirst[2]; if (collidestyle == SLIP) { - if (type == SPHERE) - slip_sphere(v[i],v[j],norm,vsnew); - else if (type == ELLIPSOID) - slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - slip_wall(v[i],j,norm,vsnew); + if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew); + else slip_wall(v[i],j,norm,vsnew); } else { - if (type != WALL) - noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - noslip_wall(v[i],j,xscoll,norm,vsnew); + if (type != WALL) noslip(v[i],v[j],x[j],big,-1,xscoll,norm,vsnew); + else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew); } if (dimension == 2) vsnew[2] = 0.0; @@ -1420,6 +1466,276 @@ int FixSRD::inside_ellipsoid(double *xs, double *xb, Big *big) return 0; } +/* ---------------------------------------------------------------------- + check if SRD particle S is inside line big particle B + collision only possible if: + S starts on positive side of infinite line, + which means it will collide with outside of rigid body made of lines + since line segments have outward normals, + when vector from first to last point is crossed with +z axis + S ends on negative side of infinite line + unlike most other inside() routines, then calculate exact collision: + solve for collision pt along infinite line + collision if pt is within endpoints of B +------------------------------------------------------------------------- */ + +int FixSRD::inside_line(double *xs, double *xb, double *vs, double *vb, + Big *big, double dt_step) +{ + double pmc0[2],pmc1[2],n0[2],n1[2]; + double n1_n0[2],pmc1_pmc0[2]; + + // 1 and 2 = start and end of timestep + // pmc = P - C, where P = position of S, C = position of B + // n = normal to line = [-sin(theta),cos(theta)], theta = orientation of B + // (P-C) dot N = side of line that S is on + // side0 = -1,0,1 for which side of line B that S is on at start of step + // side1 = -1,0,1 for which side of line B that S is on at end of step + + xs1[0] = xs[0]; + xs1[1] = xs[1]; + xb1[0] = xb[0]; + xb1[1] = xb[1]; + + xs0[0] = xs1[0] - dt_step*vs[0]; + xs0[1] = xs1[1] - dt_step*vs[1]; + xb0[0] = xb1[0] - dt_step*vb[0]; + xb0[1] = xb1[1] - dt_step*vb[1]; + + theta1 = big->theta; + theta0 = theta1 - dt_step*big->omega[2]; + + pmc0[0] = xs0[0] - xb0[0]; + pmc0[1] = xs0[1] - xb0[1]; + n0[0] = sin(theta0); + n0[1] = -cos(theta0); + + pmc1[0] = xs1[0] - xb1[0]; + pmc1[1] = xs1[1] - xb1[1]; + n1[0] = sin(theta1); + n1[1] = -cos(theta1); + + double side0 = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + double side1 = pmc1[0]*n1[0] + pmc1[1]*n1[1]; + + if (side0 <= 0.0 || side1 >= 0.0) return 0; + + // solve for time t (0 to 1) at which moving particle + // crosses infinite moving/rotating line + + // Newton-Raphson solve of full non-linear parametric equation + + tfraction = newton_raphson(0.0,1.0); + + // quadratic equation solve of approximate parametric equation + + /* + n1_n0[0] = n1[0]-n0[0]; n1_n0[1] = n1[1]-n0[1]; + pmc1_pmc0[0] = pmc1[0]-pmc0[0]; pmc1_pmc0[1] = pmc1[1]-pmc0[1]; + + double a = pmc1_pmc0[0]*n1_n0[0] + pmc1_pmc0[1]*n1_n0[1]; + double b = pmc1_pmc0[0]*n0[0] + pmc1_pmc0[1]*n0[1] + + n1_n0[0]*pmc0[0] + n1_n0[1]*pmc0[1]; + double c = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + + if (a == 0.0) { + double dot0 = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + double dot1 = pmc1[0]*n0[0] + pmc1[1]*n0[1]; + double root = -dot0 / (dot1 - dot0); + //printf("Linear root: %g %g\n",root,tfraction); + tfraction = root; + + } else { + + double term = sqrt(b*b - 4.0*a*c); + double root1 = (-b + term) / (2.0*a); + double root2 = (-b - term) / (2.0*a); + + //printf("ABC vecs: %g %g: %g %g\n", + // pmc1_pmc0[0],pmc1_pmc0[1],n1_n0[0],n1_n0[1]); + //printf("ABC vecs: %g %g: %g %g: %g %g %g\n", + // n0[0],n0[1],n1[0],n1[1],theta0,theta1,big->omega[2]); + //printf("ABC root: %g %g %g: %g %g %g\n",a,b,c,root1,root2,tfraction); + + if (0.0 <= root1 && root1 <= 1.0) tfraction = root1; + else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2; + else error->one(FLERR,"Bad quadratic solve for particle/line collision"); + } + */ + + // check if collision pt is within line segment at collision time + + xsc[0] = xs0[0] + tfraction*(xs1[0]-xs0[0]); + xsc[1] = xs0[1] + tfraction*(xs1[1]-xs0[1]); + xbc[0] = xb0[0] + tfraction*(xb1[0]-xb0[0]); + xbc[1] = xb0[1] + tfraction*(xb1[1]-xb0[1]); + double delx = xsc[0] - xbc[0]; + double dely = xsc[1] - xbc[1]; + double rsq = delx*delx + dely*dely; + if (rsq > 0.25*big->length*big->length) return 0; + + //nbc[0] = n0[0] + tfraction*(n1[0]-n0[0]); + //nbc[1] = n0[1] + tfraction*(n1[1]-n0[1]); + + nbc[0] = sin(theta0 + tfraction*(theta1-theta0)); + nbc[1] = -cos(theta0 + tfraction*(theta1-theta0)); + + return 1; +} + +/* ---------------------------------------------------------------------- + check if SRD particle S is inside triangle big particle B + collision only possible if: + S starts on positive side of triangle plane, + which means it will collide with outside of rigid body made of tris + since triangles have outward normals, + S ends on negative side of triangle plane + unlike most other inside() routines, then calculate exact collision: + solve for collision pt on triangle plane + collision if pt is inside triangle B +------------------------------------------------------------------------- */ + +int FixSRD::inside_tri(double *xs, double *xb, double *vs, double *vb, + Big *big, double dt_step) +{ + double pmc0[3],pmc1[3],n0[3]; + double n1_n0[3],pmc1_pmc0[3]; + double excoll[3],eycoll[3],ezcoll[3]; + double dc1[3],dc2[3],dc3[3]; + double c1[3],c2[3],c3[3]; + double c2mc1[3],c3mc2[3],c1mc3[3]; + double pvec[3],xproduct[3]; + + // 1 and 2 = start and end of timestep + // pmc = P - C, where P = position of S, C = position of B + // n = normal to triangle + // (P-C) dot N = side of tri that S is on + // side0 = -1,0,1 for which side of tri B that S is on at start of step + // side1 = -1,0,1 for which side of tri B that S is on at end of step + + double *omega = big->omega; + double *n1 = big->norm; + + n0[0] = n1[0] - dt_step*(omega[1]*n1[2] - omega[2]*n1[1]); + n0[1] = n1[1] - dt_step*(omega[2]*n1[0] - omega[0]*n1[2]); + n0[2] = n1[2] - dt_step*(omega[0]*n1[1] - omega[1]*n1[0]); + + pmc0[0] = xs[0] - dt_step*vs[0] - xb[0] + dt_step*vb[0]; + pmc0[1] = xs[1] - dt_step*vs[1] - xb[1] + dt_step*vb[1]; + pmc0[2] = xs[2] - dt_step*vs[2] - xb[2] + dt_step*vb[2]; + pmc1[0] = xs[0] - xb[0]; + pmc1[1] = xs[1] - xb[1]; + pmc1[2] = xs[2] - xb[2]; + + double side0 = MathExtra::dot3(pmc0,n0); + double side1 = MathExtra::dot3(pmc1,n1); + + if (side0 <= 0.0 || side1 >= 0.0) return 0; + + // solve for time t (0 to 1) at which moving particle + // crosses moving/rotating tri + // quadratic equation solve of approximate parametric equation + + n1_n0[0] = n1[0]-n0[0]; + n1_n0[1] = n1[1]-n0[1]; + n1_n0[2] = n1[2]-n0[2]; + pmc1_pmc0[0] = pmc1[0]-pmc0[0]; + pmc1_pmc0[1] = pmc1[1]-pmc0[1]; + pmc1_pmc0[2] = pmc1[2]-pmc0[2]; + + double a = MathExtra::dot3(pmc1_pmc0,n1_n0); + double b = MathExtra::dot3(pmc1_pmc0,n0) + MathExtra::dot3(n1_n0,pmc0); + double c = MathExtra::dot3(pmc0,n0); + + if (a == 0.0) { + double dot0 = MathExtra::dot3(pmc0,n0); + double dot1 = MathExtra::dot3(pmc1,n0); + double root = -dot0 / (dot1 - dot0); + tfraction = root; + } else { + double term = sqrt(b*b - 4.0*a*c); + double root1 = (-b + term) / (2.0*a); + double root2 = (-b - term) / (2.0*a); + if (0.0 <= root1 && root1 <= 1.0) tfraction = root1; + else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2; + else error->one(FLERR,"Bad quadratic solve for particle/tri collision"); + } + + // calculate position/orientation of S and B at collision time + // dt = time previous to now at which collision occurs + // point = S position in plane of triangle at collision time + // Excoll,Eycoll,Ezcoll = orientation of tri at collision time + // c1,c2,c3 = corner points of triangle at collision time + // nbc = normal to plane of triangle at collision time + + AtomVecTri::Bonus *tbonus; + tbonus = avec_tri->bonus; + + double *ex = big->ex; + double *ey = big->ey; + double *ez = big->ez; + int index = atom->tri[big->index]; + double *c1body = tbonus[index].c1; + double *c2body = tbonus[index].c2; + double *c3body = tbonus[index].c3; + + double dt = (1.0-tfraction)*dt_step; + + xsc[0] = xs[0] - dt*vs[0]; + xsc[1] = xs[1] - dt*vs[1]; + xsc[2] = xs[2] - dt*vs[2]; + xbc[0] = xb[0] - dt*vb[0]; + xbc[1] = xb[1] - dt*vb[1]; + xbc[2] = xb[2] - dt*vb[2]; + + excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]); + excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]); + excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]); + + eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]); + eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]); + eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]); + + ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]); + ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]); + ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]); + + MathExtra::matvec(excoll,eycoll,ezcoll,c1body,dc1); + MathExtra::matvec(excoll,eycoll,ezcoll,c2body,dc2); + MathExtra::matvec(excoll,eycoll,ezcoll,c3body,dc3); + + MathExtra::add3(xbc,dc1,c1); + MathExtra::add3(xbc,dc2,c2); + MathExtra::add3(xbc,dc3,c3); + + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c2,c3mc2); + MathExtra::sub3(c1,c3,c1mc3); + + MathExtra::cross3(c2mc1,c3mc2,nbc); + MathExtra::norm3(nbc); + + // check if collision pt is within triangle + // pvec = vector from tri vertex to intersection point + // xproduct = cross product of edge vec with pvec + // if dot product of xproduct with nbc < 0.0 for any of 3 edges, + // intersection point is outside tri + + MathExtra::sub3(xsc,c1,pvec); + MathExtra::cross3(c2mc1,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + MathExtra::sub3(xsc,c2,pvec); + MathExtra::cross3(c3mc2,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + MathExtra::sub3(xsc,c3,pvec); + MathExtra::cross3(c1mc3,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + return 1; +} + /* ---------------------------------------------------------------------- check if SRD particle S is inside wall IWALL ------------------------------------------------------------------------- */ @@ -1451,7 +1767,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb, double vs_dot_vs,vb_dot_vb,vs_dot_vb; double vs_dot_xb,vb_dot_xs,vs_dot_xs,vb_dot_xb; double xs_dot_xs,xb_dot_xb,xs_dot_xb; - double a,b,c,scale,dt; + double a,b,c,scale; vs_dot_vs = vs[0]*vs[0] + vs[1]*vs[1] + vs[2]*vs[2]; vb_dot_vb = vb[0]*vb[0] + vb[1]*vb[1] + vb[2]*vb[2]; @@ -1470,7 +1786,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb, b = 2.0 * (vs_dot_xb + vb_dot_xs - vs_dot_xs - vb_dot_xb); c = xs_dot_xs + xb_dot_xb - 2.0*xs_dot_xb - big->radsq; - dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); + double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); xscoll[0] = xs[0] - dt*vs[0]; xscoll[1] = xs[1] - dt*vs[1]; @@ -1541,7 +1857,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, double vs_vb[3],xs_xb[3],omega_ex[3],omega_ey[3],omega_ez[3]; double excoll[3],eycoll[3],ezcoll[3],delta[3],xbody[3],nbody[3]; double ax,bx,cx,ay,by,cy,az,bz,cz; - double a,b,c,dt,scale; + double a,b,c,scale; double *omega = big->omega; double *ex = big->ex; @@ -1551,17 +1867,9 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, vs_vb[0] = vs[0]-vb[0]; vs_vb[1] = vs[1]-vb[1]; vs_vb[2] = vs[2]-vb[2]; xs_xb[0] = xs[0]-xb[0]; xs_xb[1] = xs[1]-xb[1]; xs_xb[2] = xs[2]-xb[2]; - omega_ex[0] = omega[1]*ex[2] - omega[2]*ex[1]; - omega_ex[1] = omega[2]*ex[0] - omega[0]*ex[2]; - omega_ex[2] = omega[0]*ex[1] - omega[1]*ex[0]; - - omega_ey[0] = omega[1]*ey[2] - omega[2]*ey[1]; - omega_ey[1] = omega[2]*ey[0] - omega[0]*ey[2]; - omega_ey[2] = omega[0]*ey[1] - omega[1]*ey[0]; - - omega_ez[0] = omega[1]*ez[2] - omega[2]*ez[1]; - omega_ez[1] = omega[2]*ez[0] - omega[0]*ez[2]; - omega_ez[2] = omega[0]*ez[1] - omega[1]*ez[0]; + MathExtra::cross3(omega,ex,omega_ex); + MathExtra::cross3(omega,ey,omega_ey); + MathExtra::cross3(omega,ez,omega_ez); ax = vs_vb[0]*omega_ex[0] + vs_vb[1]*omega_ex[1] + vs_vb[2]*omega_ex[2]; bx = -(vs_vb[0]*ex[0] + vs_vb[1]*ex[1] + vs_vb[2]*ex[2]); @@ -1586,7 +1894,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, c = cx*cx*big->aradsqinv + cy*cy*big->bradsqinv + cz*cz*big->cradsqinv - 1.0; - dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); + double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); xscoll[0] = xs[0] - dt*vs[0]; xscoll[1] = xs[1] - dt*vs[1]; @@ -1602,37 +1910,27 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, // norm = normal in space frame // only worry about normalizing final norm vector - excoll[0] = ex[0] - dt * (omega[1]*ex[2] - omega[2]*ex[1]); - excoll[1] = ex[1] - dt * (omega[2]*ex[0] - omega[0]*ex[2]); - excoll[2] = ex[2] - dt * (omega[0]*ex[1] - omega[1]*ex[0]); + excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]); + excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]); + excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]); - eycoll[0] = ey[0] - dt * (omega[1]*ey[2] - omega[2]*ey[1]); - eycoll[1] = ey[1] - dt * (omega[2]*ey[0] - omega[0]*ey[2]); - eycoll[2] = ey[2] - dt * (omega[0]*ey[1] - omega[1]*ey[0]); + eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]); + eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]); + eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]); - ezcoll[0] = ez[0] - dt * (omega[1]*ez[2] - omega[2]*ez[1]); - ezcoll[1] = ez[1] - dt * (omega[2]*ez[0] - omega[0]*ez[2]); - ezcoll[2] = ez[2] - dt * (omega[0]*ez[1] - omega[1]*ez[0]); + ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]); + ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]); + ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]); - delta[0] = xscoll[0] - xbcoll[0]; - delta[1] = xscoll[1] - xbcoll[1]; - delta[2] = xscoll[2] - xbcoll[2]; - - xbody[0] = delta[0]*excoll[0] + delta[1]*excoll[1] + delta[2]*excoll[2]; - xbody[1] = delta[0]*eycoll[0] + delta[1]*eycoll[1] + delta[2]*eycoll[2]; - xbody[2] = delta[0]*ezcoll[0] + delta[1]*ezcoll[1] + delta[2]*ezcoll[2]; + MathExtra::sub3(xscoll,xbcoll,delta); + MathExtra::transpose_matvec(excoll,eycoll,ezcoll,delta,xbody); nbody[0] = xbody[0]*big->aradsqinv; nbody[1] = xbody[1]*big->bradsqinv; nbody[2] = xbody[2]*big->cradsqinv; - norm[0] = excoll[0]*nbody[0] + eycoll[0]*nbody[1] + ezcoll[0]*nbody[2]; - norm[1] = excoll[1]*nbody[0] + eycoll[1]*nbody[1] + ezcoll[1]*nbody[2]; - norm[2] = excoll[2]*nbody[0] + eycoll[2]*nbody[1] + ezcoll[2]*nbody[2]; - scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); - norm[0] *= scale; - norm[1] *= scale; - norm[2] *= scale; + MathExtra::matvec(excoll,eycoll,ezcoll,nbody,norm); + MathExtra::norm3(norm); return dt; } @@ -1640,6 +1938,10 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, /* ---------------------------------------------------------------------- collision of SRD particle S with surface of ellipsoidal big particle B inexact because just push SRD to surface of big particle at end of step + time of collision = end of step + xscoll = collision pt = position of SRD at time of collision + xbcoll = xb = position of big particle at time of collision + norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, @@ -1648,22 +1950,18 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, double *norm) { double xs_xb[3],delta[3],xbody[3],nbody[3]; - double x,y,z,scale; double *ex = big->ex; double *ey = big->ey; double *ez = big->ez; - xs_xb[0] = xs[0] - xb[0]; - xs_xb[1] = xs[1] - xb[1]; - xs_xb[2] = xs[2] - xb[2]; + MathExtra::sub3(xs,xb,xs_xb); + double x = MathExtra::dot3(xs_xb,ex); + double y = MathExtra::dot3(xs_xb,ey); + double z = MathExtra::dot3(xs_xb,ez); - x = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2]; - y = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2]; - z = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2]; - - scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv + - z*z*big->cradsqinv); + double scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv + + z*z*big->cradsqinv); x *= scale; y *= scale; z *= scale; @@ -1681,25 +1979,73 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, // norm = normal in space frame // only worry about normalizing final norm vector - delta[0] = xscoll[0] - xbcoll[0]; - delta[1] = xscoll[1] - xbcoll[1]; - delta[2] = xscoll[2] - xbcoll[2]; - - xbody[0] = delta[0]*ex[0] + delta[1]*ex[1] + delta[2]*ex[2]; - xbody[1] = delta[0]*ey[0] + delta[1]*ey[1] + delta[2]*ey[2]; - xbody[2] = delta[0]*ez[0] + delta[1]*ez[1] + delta[2]*ez[2]; + MathExtra::sub3(xscoll,xbcoll,delta); + MathExtra::transpose_matvec(ex,ey,ez,delta,xbody); nbody[0] = xbody[0]*big->aradsqinv; nbody[1] = xbody[1]*big->bradsqinv; nbody[2] = xbody[2]*big->cradsqinv; - norm[0] = ex[0]*nbody[0] + ey[0]*nbody[1] + ez[0]*nbody[2]; - norm[1] = ex[1]*nbody[0] + ey[1]*nbody[1] + ez[1]*nbody[2]; - norm[2] = ex[2]*nbody[0] + ey[2]*nbody[1] + ez[2]*nbody[2]; - scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); - norm[0] *= scale; - norm[1] *= scale; - norm[2] *= scale; + MathExtra::matvec(ex,ey,ez,nbody,norm); + MathExtra::norm3(norm); +} + +/* ---------------------------------------------------------------------- + collision of SRD particle S with surface of line big particle B + exact because compute time of collision + dt = time previous to now at which collision occurs + xscoll = collision pt = position of SRD at time of collision + xbcoll = position of big particle at time of collision + norm = surface normal of collision pt at time of collision +------------------------------------------------------------------------- */ + +double FixSRD::collision_line_exact(double *xs, double *xb, + double *vs, double *vb, Big *big, + double dt_step, + double *xscoll, double *xbcoll, + double *norm) +{ + xscoll[0] = xsc[0]; + xscoll[1] = xsc[1]; + xscoll[2] = 0.0; + xbcoll[0] = xbc[0]; + xbcoll[1] = xbc[1]; + xbcoll[2] = 0.0; + + norm[0] = nbc[0]; + norm[1] = nbc[1]; + norm[2] = 0.0; + + return (1.0-tfraction)*dt_step; +} + +/* ---------------------------------------------------------------------- + collision of SRD particle S with surface of triangle big particle B + exact because compute time of collision + dt = time previous to now at which collision occurs + xscoll = collision pt = position of SRD at time of collision + xbcoll = position of big particle at time of collision + norm = surface normal of collision pt at time of collision +------------------------------------------------------------------------- */ + +double FixSRD::collision_tri_exact(double *xs, double *xb, + double *vs, double *vb, Big *big, + double dt_step, + double *xscoll, double *xbcoll, + double *norm) +{ + xscoll[0] = xsc[0]; + xscoll[1] = xsc[1]; + xscoll[2] = xsc[2]; + xbcoll[0] = xbc[0]; + xbcoll[1] = xbc[1]; + xbcoll[2] = xbc[2]; + + norm[0] = nbc[0]; + norm[1] = nbc[1]; + norm[2] = nbc[2]; + + return (1.0-tfraction)*dt_step; } /* ---------------------------------------------------------------------- @@ -1707,6 +2053,7 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, exact because compute time of collision dt = time previous to now at which collision occurs xscoll = collision pt = position of SRD at time of collision + xbcoll = position of wall at time of collision norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ @@ -1737,6 +2084,7 @@ double FixSRD::collision_wall_exact(double *xs, int iwall, double *vs, inexact because just push SRD to surface of wall at end of step time of collision = end of step xscoll = collision pt = position of SRD at time of collision + xbcoll = position of wall at time of collision norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ @@ -1760,54 +2108,18 @@ void FixSRD::collision_wall_inexact(double *xs, int iwall, double *xscoll, } /* ---------------------------------------------------------------------- - SLIP collision with sphere - vs = velocity of SRD, vb = velocity of BIG - norm = unit normal from surface of BIG at collision pt - v of BIG particle in direction of surf normal is added to v of SRD - return vsnew of SRD -------------------------------------------------------------------------- */ - -void FixSRD::slip_sphere(double *vs, double *vb, double *norm, double *vsnew) -{ - double r1,r2,vnmag,vs_dot_n,vsurf_dot_n; - double tangent[3]; - - while (1) { - r1 = sigma * random->gaussian(); - r2 = sigma * random->gaussian(); - vnmag = sqrt(r1*r1 + r2*r2); - if (vnmag*vnmag <= vmaxsq) break; - } - - vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; - - tangent[0] = vs[0] - vs_dot_n*norm[0]; - tangent[1] = vs[1] - vs_dot_n*norm[1]; - tangent[2] = vs[2] - vs_dot_n*norm[2]; - - // vsurf = velocity of collision pt = translation/rotation of BIG particle - // for sphere, only vb (translation) can contribute in normal direction - - vsurf_dot_n = vb[0]*norm[0] + vb[1]*norm[1] + vb[2]*norm[2]; - - vsnew[0] = (vnmag+vsurf_dot_n)*norm[0] + tangent[0]; - vsnew[1] = (vnmag+vsurf_dot_n)*norm[1] + tangent[1]; - vsnew[2] = (vnmag+vsurf_dot_n)*norm[2] + tangent[2]; -} - -/* ---------------------------------------------------------------------- - SLIP collision with ellipsoid + SLIP collision with BIG particle with omega vs = velocity of SRD, vb = velocity of BIG xb = position of BIG, omega = rotation of BIG xsurf = collision pt on surf of BIG norm = unit normal from surface of BIG at collision pt v of BIG particle in direction of surf normal is added to v of SRD - includes component due to rotation of ellipsoid + includes component due to rotation of BIG return vsnew of SRD ------------------------------------------------------------------------- */ -void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big, - double *xsurf, double *norm, double *vsnew) +void FixSRD::slip(double *vs, double *vb, double *xb, Big *big, + double *xsurf, double *norm, double *vsnew) { double r1,r2,vnmag,vs_dot_n,vsurf_dot_n; double tangent[3],vsurf[3]; @@ -1827,6 +2139,8 @@ void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big, tangent[2] = vs[2] - vs_dot_n*norm[2]; // vsurf = velocity of collision pt = translation/rotation of BIG particle + // NOTE: for sphere could just use vsurf = vb, since w x (xsurf-xb) + // is orthogonal to norm and thus doesn't contribute to vsurf_dot_n vsurf[0] = vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); vsurf[1] = vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); @@ -1887,7 +2201,7 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew) } /* ---------------------------------------------------------------------- - NO-SLIP collision with sphere or ellipsoid + NO-SLIP collision with BIG particle including WALL vs = velocity of SRD, vb = velocity of BIG xb = position of BIG, omega = rotation of BIG xsurf = collision pt on surf of BIG @@ -1897,12 +2211,11 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew) return vsnew of SRD ------------------------------------------------------------------------- */ -void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, +void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, int iwall, double *xsurf, double *norm, double *vsnew) { double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2; double tangent1[3],tangent2[3]; - double *omega = big->omega; vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; @@ -1932,60 +2245,20 @@ void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1]; vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2]; - // add in velocity of collision pt = translation/rotation of BIG particle + // add in velocity of collision pt + // for WALL: velocity of wall in one dim + // else: translation/rotation of BIG particle - vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); - vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); - vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]); -} + if (big->type == WALL) { + int dim = wallwhich[iwall] / 2; + vsnew[dim] += vwall[iwall]; -/* ---------------------------------------------------------------------- - NO-SLIP collision with wall IWALL - vs = velocity of SRD - xsurf = collision pt on surf of WALL - norm = unit normal from WALL at collision pt - v of collision pt is added to v of SRD - return vsnew of SRD -------------------------------------------------------------------------- */ - -void FixSRD::noslip_wall(double *vs, int iwall, - double *xsurf, double *norm, double *vsnew) -{ - double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2; - double tangent1[3],tangent2[3]; - - vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; - - tangent1[0] = vs[0] - vs_dot_n*norm[0]; - tangent1[1] = vs[1] - vs_dot_n*norm[1]; - tangent1[2] = vs[2] - vs_dot_n*norm[2]; - scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] + - tangent1[2]*tangent1[2]); - tangent1[0] *= scale; - tangent1[1] *= scale; - tangent1[2] *= scale; - - tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1]; - tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2]; - tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0]; - - while (1) { - r1 = sigma * random->gaussian(); - r2 = sigma * random->gaussian(); - vnmag = sqrt(r1*r1 + r2*r2); - vtmag1 = sigma * random->gaussian(); - vtmag2 = sigma * random->gaussian(); - if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break; + } else { + double *omega = big->omega; + vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); + vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); + vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]); } - - vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0]; - vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1]; - vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2]; - - // add in velocity of collision pt = velocity of wall - - int dim = wallwhich[iwall] / 2; - vsnew[dim] += vwall[iwall]; } /* ---------------------------------------------------------------------- @@ -2027,6 +2300,7 @@ void FixSRD::force_torque(double *vsold, double *vsnew, ------------------------------------------------------------------------- */ void FixSRD::force_wall(double *vsold, double *vsnew, int iwall) + { double dpdt[3]; @@ -2100,12 +2374,20 @@ void FixSRD::parameterize() AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double *radius = atom->radius; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *mask = atom->mask; int nlocal = atom->nlocal; - any_ellipsoids = 0; + int any_ellipsoids = 0; + int any_lines = 0; + int any_tris = 0; maxbigdiam = 0.0; minbigdiam = BIG; @@ -2123,6 +2405,20 @@ void FixSRD::parameterize() minbigdiam = MIN(minbigdiam,2.0*shape[0]); minbigdiam = MIN(minbigdiam,2.0*shape[1]); minbigdiam = MIN(minbigdiam,2.0*shape[2]); + } else if (line && line[i] >= 0) { + any_lines = 1; + double length = lbonus[line[i]].length; + maxbigdiam = MAX(maxbigdiam,length); + minbigdiam = MIN(minbigdiam,length); + } else if (tri && tri[i] >= 0) { + any_tris = 1; + double length1 = MathExtra::len3(tbonus[tri[i]].c1); + double length2 = MathExtra::len3(tbonus[tri[i]].c2); + double length3 = MathExtra::len3(tbonus[tri[i]].c3); + double length = MAX(length1,length2); + length = MAX(length,length3); + maxbigdiam = MAX(maxbigdiam,length); + minbigdiam = MIN(minbigdiam,length); } else error->one(FLERR,"Big particle in fix srd cannot be point particle"); } @@ -2137,10 +2433,20 @@ void FixSRD::parameterize() int itmp = any_ellipsoids; MPI_Allreduce(&itmp,&any_ellipsoids,1,MPI_INT,MPI_MAX,world); + itmp = any_lines; + MPI_Allreduce(&itmp,&any_lines,1,MPI_INT,MPI_MAX,world); + itmp = any_tris; + MPI_Allreduce(&itmp,&any_tris,1,MPI_INT,MPI_MAX,world); - // big particles are only torqued if are ellipsoids or NOSLIP collisions + if (any_lines && overlap == 0) + error->all(FLERR,"Cannot use lines with fix srd unless overlap is set"); + if (any_tris && overlap == 0) + error->all(FLERR,"Cannot use tris with fix srd unless overlap is set"); - if (any_ellipsoids == 0 && collidestyle == SLIP) torqueflag = 0; + // big particles are only torqued if ellipsoids/lines/tris or NOSLIP + + if (any_ellipsoids == 0 && any_lines == 0 && any_tris == 0 && + collidestyle == SLIP) torqueflag = 0; else torqueflag = 1; // mass of SRD particles, require monodispersity @@ -2186,28 +2492,46 @@ void FixSRD::parameterize() vmaxsq = vmax*vmax; // volbig = total volume of all big particles + // LINE/TRI particles have no volume + // incorrect if part of rigid particles, so add fudge factor with WIDTH // apply radfactor to reduce final volume double volbig = 0.0; + double WIDTH = 1.0; if (dimension == 3) { for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { - if (radius && radius[i] > 0.0) - volbig += 4.0/3.0*MY_PI*radius[i]*radius[i]*radius[i]; - else if (ellipsoid && ellipsoid[i] >= 0) { + if (radius && radius[i] > 0.0) { + double r = radfactor * radius[i]; + volbig += 4.0/3.0*MY_PI * r*r*r;; + } else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2]; + volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2] * + radfactor*radfactor*radfactor; + } else if (tri && tri[i] >= 0) { + double *c1 = tbonus[tri[i]].c1; + double *c2 = tbonus[tri[i]].c2; + double *c3 = tbonus[tri[i]].c3; + double c2mc1[3],c3mc1[3],cross[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + MathExtra::cross3(c2mc1,c3mc1,cross); + volbig += 0.5 * MathExtra::len3(cross); } } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { - if (radius && radius[i] > 0.0) - volbig += MY_PI*radius[i]*radius[i]; - else if (ellipsoid && ellipsoid[i] >= 0) { + if (radius && radius[i] > 0.0) { + double r = radfactor * radius[i]; + volbig += MY_PI * r*r; + } else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += MY_PI*shape[0]*shape[1]; + volbig += MY_PI * shape[0]*shape[1] * radfactor*radfactor; + } else if (line && line[i] >= 0) { + double length = lbonus[line[i]].length; + volbig += length * WIDTH; } } } @@ -2215,9 +2539,6 @@ void FixSRD::parameterize() tmp = volbig; MPI_Allreduce(&tmp,&volbig,1,MPI_DOUBLE,MPI_SUM,world); - if (dimension == 3) volbig *= radfactor*radfactor*radfactor; - else volbig *= radfactor*radfactor; - // particle counts bigint mbig = 0; @@ -2228,7 +2549,10 @@ void FixSRD::parameterize() mass_big = 0.0; for (int i = 0; i < nlocal; i++) - if (mask[i] & biggroupbit) mass_big += rmass[i]; + if (mask[i] & biggroupbit) { + if (rmass) mass_big += rmass[i]; + else mass_big += mass[type[i]]; + } tmp = mass_big; MPI_Allreduce(&tmp,&mass_big,1,MPI_DOUBLE,MPI_SUM,world); @@ -2369,7 +2693,8 @@ void FixSRD::parameterize() if (cubicflag == CUBIC_ERROR) error->all(FLERR,"SRD bin size for fix srd differs from user request"); if (me == 0) - error->warning(FLERR,"SRD bin size for fix srd differs from user request"); + error->warning(FLERR, + "SRD bin size for fix srd differs from user request"); } // error if lamda < 0.6 of SRD grid size and no shifting allowed @@ -2400,30 +2725,46 @@ void FixSRD::parameterize() /* ---------------------------------------------------------------------- set static parameters of each big particle, owned and ghost called each reneighboring - use radfactor in distance parameters + use radfactor in distance parameters as appropriate ------------------------------------------------------------------------- */ void FixSRD::big_static() { int i; - double rad,arad,brad,crad; - double *shape; + double rad,arad,brad,crad,length,length1,length2,length3; + double *shape,*c1,*c2,*c3; + double c2mc1[3],c3mc1[3]; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double *radius = atom->radius; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; + int *type = atom->type; double skinhalf = 0.5 * neighbor->skin; for (int k = 0; k < nbig; k++) { i = biglist[k].index; + + // sphere + // set radius and radsq and cutoff based on radius + if (radius && radius[i] > 0.0) { biglist[k].type = SPHERE; rad = radfactor*radius[i]; biglist[k].radius = rad; biglist[k].radsq = rad*rad; biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // ellipsoid + // set abc radsqinv and cutoff based on max radius + } else if (ellipsoid && ellipsoid[i] >= 0) { shape = ebonus[ellipsoid[i]].shape; biglist[k].type = ELLIPSOID; @@ -2436,33 +2777,67 @@ void FixSRD::big_static() rad = MAX(arad,brad); rad = MAX(rad,crad); biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // line + // set length and cutoff based on 1/2 length + + } else if (line && line[i] >= 0) { + length = lbonus[line[i]].length; + biglist[k].type = LINE; + biglist[k].length = length; + rad = 0.5*length; + biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // tri + // set normbody based on c1,c2,c3 + // set cutoff based on point furthest from centroid + + } else if (tri && tri[i] >= 0) { + biglist[k].type = TRIANGLE; + c1 = tbonus[tri[i]].c1; + c2 = tbonus[tri[i]].c2; + c3 = tbonus[tri[i]].c3; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + MathExtra::cross3(c2mc1,c3mc1,biglist[k].normbody); + length1 = MathExtra::len3(c1); + length2 = MathExtra::len3(c2); + length3 = MathExtra::len3(c3); + rad = MAX(length1,length2); + rad = MAX(rad,length3); + biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); } } } /* ---------------------------------------------------------------------- - set dynamics parameters of each big particle, owned and ghost - for ELLIPSOID, need current omega and ex,ey,ez - for SPHERE, need current omega from atom->omega or atom->angmom + set dynamic parameters of each big particle, owned and ghost called each timestep ------------------------------------------------------------------------- */ void FixSRD::big_dynamic() { int i; - double *shape,*quat; + double *shape,*quat,*inertia; + double inertiaone[3]; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega = atom->omega; double **angmom = atom->angmom; double *rmass = atom->rmass; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; for (int k = 0; k < nbig; k++) { i = biglist[k].index; - // sphere with omega + // sphere // set omega from atom->omega directly if (biglist[k].type == SPHERE) { @@ -2470,15 +2845,45 @@ void FixSRD::big_dynamic() biglist[k].omega[1] = omega[i][1]; biglist[k].omega[2] = omega[i][2]; - // ellipsoid with angmom - // calculate ex,ey,ez and omega from quaternion and angmom + // ellipsoid + // set ex,ey,ez from quaternion + // set omega from angmom & ex,ey,ez } else if (biglist[k].type == ELLIPSOID) { - shape = ebonus[ellipsoid[i]].shape; quat = ebonus[ellipsoid[i]].quat; - exyz_from_q(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); - omega_from_mq(angmom[i],biglist[k].ex,biglist[k].ey,biglist[k].ez, - rmass[i],shape,biglist[k].omega); + MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); + shape = ebonus[ellipsoid[i]].shape; + inertiaone[0] = EINERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); + inertiaone[1] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); + inertiaone[2] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); + MathExtra::angmom_to_omega(angmom[i], + biglist[k].ex,biglist[k].ey,biglist[k].ez, + inertiaone,biglist[k].omega); + + // line + // set omega from atom->omega directly + + } else if (biglist[k].type == LINE) { + biglist[k].theta = lbonus[line[i]].theta; + biglist[k].omega[0] = omega[i][0]; + biglist[k].omega[1] = omega[i][1]; + biglist[k].omega[2] = omega[i][2]; + + // tri + // set ex,ey,ez from quaternion + // set omega from angmom & ex,ey,ez + // set unit space-frame norm from body-frame norm + + } else if (biglist[k].type == TRIANGLE) { + quat = tbonus[tri[i]].quat; + MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); + inertia = tbonus[tri[i]].inertia; + MathExtra::angmom_to_omega(angmom[i], + biglist[k].ex,biglist[k].ey,biglist[k].ez, + inertia,biglist[k].omega); + MathExtra::matvec(biglist[k].ex,biglist[k].ey,biglist[k].ez, + biglist[k].normbody,biglist[k].norm); + MathExtra::norm3(biglist[k].norm); } } } @@ -2967,10 +3372,10 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic) for (m = 0; m < nsend; m++) vbin[sendlist[m]].owner = 0; } - // if triclinic and streamflag: - // set xctr (in lamda units) for all nbins so can compute bin vstream + // if tstat and deformflag: + // set xctr for all nbins in lamda units so can later compute vstream of bin - if (triclinic && streamflag) { + if (tstat && deformflag) { m = 0; for (k = 0; k < nbinz; k++) for (j = 0; j < nbiny; j++) @@ -3182,55 +3587,6 @@ double FixSRD::bin_bin_distance(int i, int j, int k) return (delx*delx + dely*dely + delz*delz); } -/* ---------------------------------------------------------------------- - compute space-frame ex,ey,ez from current quaternion q - ex,ey,ez = space-frame coords of 1st,2nd,3rd principal axis - operation is ex = q' d q = Q d, where d is (1,0,0) = 1st axis in body frame -------------------------------------------------------------------------- */ - -void FixSRD::exyz_from_q(double *q, double *ex, double *ey, double *ez) -{ - ex[0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3]; - ex[1] = 2.0 * (q[1]*q[2] + q[0]*q[3]); - ex[2] = 2.0 * (q[1]*q[3] - q[0]*q[2]); - - ey[0] = 2.0 * (q[1]*q[2] - q[0]*q[3]); - ey[1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3]; - ey[2] = 2.0 * (q[2]*q[3] + q[0]*q[1]); - - ez[0] = 2.0 * (q[1]*q[3] + q[0]*q[2]); - ez[1] = 2.0 * (q[2]*q[3] - q[0]*q[1]); - ez[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; -} - -/* ---------------------------------------------------------------------- - compute omega from angular momentum - w = omega = angular velocity in space frame - wbody = angular velocity in body frame - set wbody component to 0.0 if inertia component is 0.0 - otherwise body can spin easily around that axis - project space-frame angular momentum onto body axes - and divide by principal moments -------------------------------------------------------------------------- */ - -void FixSRD::omega_from_mq(double *m, double *ex, double *ey, double *ez, - double mass, double *shape, double *w) -{ - double inertia[3],wbody[3]; - - inertia[0] = 0.2*mass * (shape[1]*shape[1]+shape[2]*shape[2]); - inertia[1] = 0.2*mass * (shape[0]*shape[0]+shape[2]*shape[2]); - inertia[2] = 0.2*mass * (shape[0]*shape[0]+shape[1]*shape[1]); - - wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0]; - wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1]; - wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / inertia[2]; - - w[0] = wbody[0]*ex[0] + wbody[1]*ey[0] + wbody[2]*ez[0]; - w[1] = wbody[0]*ex[1] + wbody[1]*ey[1] + wbody[2]*ez[1]; - w[2] = wbody[0]*ex[2] + wbody[1]*ey[2] + wbody[2]*ez[2]; -} - /* ---------------------------------------------------------------------- */ int FixSRD::pack_reverse_comm(int n, int first, double *buf) @@ -3365,6 +3721,90 @@ void FixSRD::velocity_stats(int groupnum) /* ---------------------------------------------------------------------- */ +double FixSRD::newton_raphson(double t1, double t2) +{ + double f1,f2,df,tlo,thi; + lineside(t1,f1,df); + if (f1 < 0.0) { + tlo = t1; + thi = t2; + } else { + thi = t1; + tlo = t2; + } + + double f; + double t = 0.5*(t1+t2); + double dtold = fabs(t2-t1); + double dt = dtold; + lineside(t,f,df); + + double temp; + for (int i = 0; i < MAXITER; i++) { + if ((((t-thi)*df - f)*((t-tlo)*df - f) > 0.0) || + (fabs(2.0*f) > fabs(dtold*df))) { + dtold = dt; + dt = 0.5 * (thi-tlo); + t = tlo + dt; + if (tlo == t) return t; + } else { + dtold = dt; + dt = f / df; + temp = t; + t -= dt; + if (temp == t) return t; + } + if (fabs(dt) < TOLERANCE) return t; + lineside(t,f,df); + if (f < 0.0) tlo = t; + else thi = t; + } + + return t; +} + +/* ---------------------------------------------------------------------- */ + +void FixSRD::lineside(double t, double &f, double &df) +{ + double p[2],c[2]; + + p[0] = xs0[0] + (xs1[0]-xs0[0])*t; + p[1] = xs0[1] + (xs1[1]-xs0[1])*t; + c[0] = xb0[0] + (xb1[0]-xb0[0])*t; + c[1] = xb0[1] + (xb1[1]-xb0[1])*t; + double dtheta = theta1 - theta0; + double theta = theta0 + dtheta*t; + double cosT = cos(theta); + double sinT = sin(theta); + + f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT; + df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta - + ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta; +} + +/* ---------------------------------------------------------------------- */ + +void FixSRD::triside(double t, double &f, double &df) +{ + double p[2],c[2]; + + p[0] = xs0[0] + (xs1[0]-xs0[0])*t; + p[1] = xs0[1] + (xs1[1]-xs0[1])*t; + c[0] = xb0[0] + (xb1[0]-xb0[0])*t; + c[1] = xb0[1] + (xb1[1]-xb0[1])*t; + double dtheta = theta1 - theta0; + double theta = theta0 + dtheta*t; + double cosT = cos(theta); + double sinT = sin(theta); + + f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT; + df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta - + ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta; +} + +/* ---------------------------------------------------------------------- */ + double FixSRD::memory_usage() { double bytes = 0.0; diff --git a/src/SRD/fix_srd.h b/src/SRD/fix_srd.h index 8552078e6d..43d9f7c2e3 100644 --- a/src/SRD/fix_srd.h +++ b/src/SRD/fix_srd.h @@ -43,9 +43,9 @@ class FixSRD : public Fix { int me,nprocs; int bigexist,biggroup,biggroupbit; int collidestyle,lamdaflag,overlap,insideflag,exactflag,maxbounceallow; - int cubicflag,shiftuser,shiftseed,shiftflag,streamflag; + int cubicflag,shiftuser,shiftseed,shiftflag,tstat; double gridsrd,gridsearch,lamda,radfactor,cubictol; - int triclinic,change_size,change_shape; + int triclinic,change_size,change_shape,deformflag; double dt_big,dt_srd; double mass_big,mass_srd; @@ -64,6 +64,8 @@ class FixSRD : public Fix { double walltrigger; class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; // for orthogonal box, these are in box units // for triclinic box, these are in lamda units @@ -92,18 +94,21 @@ class FixSRD : public Fix { struct Big { int index; // local index of particle/wall - int type; // SPHERE or ELLIPSOID or WALL + int type; // SPHERE or ELLIPSOID or LINE or TRI or WALL double radius,radsq; // radius of sphere double aradsqinv; // 3 ellipsoid radii double bradsqinv; double cradsqinv; + double length; // length of line segment + double normbody[3]; // normal of tri in body-frame double cutbinsq; // add big to bin if within this distance - double omega[3]; // current omega for sphere or ellipsoid - double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid + double omega[3]; // current omega for sphere/ellipsoid/tri/line + double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid/tri + double norm[3]; // current unit normal of tri in space-frame + double theta; // current orientation of line }; Big *biglist; // list of info for each owned & ghost big and wall - int any_ellipsoids; // 1 if any big particles are ellipsoids int torqueflag; // 1 if any big particle is torqued // current size of particle-based arrays @@ -123,7 +128,7 @@ class FixSRD : public Fix { int owner; // 1 if I am owner of this bin, 0 if not int n; // # of SRD particles in bin double xctr[3]; // center point of bin, only used for triclinic - double vave[3]; // sum of v components for SRD particles in bin + double vsum[3]; // sum of v components for SRD particles in bin double random; // random value if I am owner }; @@ -167,6 +172,17 @@ class FixSRD : public Fix { int maxstencil; // max # of bins stencil array can hold int **stencil; // list of 3d bin offsets a big particle can overlap + // persistent data for line/tri collision calculations + + double tfraction,theta0,theta1; + double xs0[3],xs1[3],xsc[3]; + double xb0[3],xb1[3],xbc[3]; + double nbc[3]; + + // shared data for triangle collision calculations + + // private functions + void reset_velocities(); void vbin_comm(int); void vbin_pack(BinAve *, int, int *, double *); @@ -177,6 +193,8 @@ class FixSRD : public Fix { int inside_sphere(double *, double *, Big *); int inside_ellipsoid(double *, double *, Big *); + int inside_line(double *, double *, double *, double *, Big *, double); + int inside_tri(double *, double *, double *, double *, Big *, double); int inside_wall(double *, int); double collision_sphere_exact(double *, double *, double *, double *, @@ -187,18 +205,19 @@ class FixSRD : public Fix { Big *, double *, double *, double *); void collision_ellipsoid_inexact(double *, double *, Big *, double *, double *, double *); + double collision_line_exact(double *, double *, double *, double *, + Big *, double, double *, double *, double *); + double collision_tri_exact(double *, double *, double *, double *, + Big *, double, double *, double *, double *); double collision_wall_exact(double *, int, double *, double *, double *, double *); void collision_wall_inexact(double *, int, double *, double *, double *); - void slip_sphere(double *, double *, double *, double *); - void slip_ellipsoid(double *, double *, double *, Big *, - double *, double *, double *); + void slip(double *, double *, double *, Big *, + double *, double *, double *); void slip_wall(double *, int, double *, double *); - - void noslip(double *, double *, double *, Big *, + void noslip(double *, double *, double *, Big *, int, double *, double *, double *); - void noslip_wall(double *, int, double *, double *, double *); void force_torque(double *, double *, double *, double *, double *, double *); @@ -217,11 +236,12 @@ class FixSRD : public Fix { double point_bin_distance(double *, int, int, int); double bin_bin_distance(int, int, int); - void exyz_from_q(double *, double *, double *, double *); - void omega_from_mq(double *, double *, double *, double *, - double, double *, double *); void velocity_stats(int); + double newton_raphson(double, double); + void lineside(double, double &, double &); + void triside(double, double &, double &); + double distance(int, int); void print_collision(int, int, int, double, double, double *, double *, double *, int); diff --git a/src/atom.cpp b/src/atom.cpp index f42b1250f1..023d7a173f 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -75,7 +75,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) radius = rmass = NULL; vfrac = s0 = NULL; x0 = NULL; - ellipsoid = NULL; + ellipsoid = line = tri = NULL; spin = NULL; eradius = ervel = erforce = NULL; cs = csforce = vforce = ervelforce = NULL; @@ -106,7 +106,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) // initialize atom style and array existence flags // customize by adding new flag - sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0; + sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0; + peri_flag = electron_flag = 0; wavepacket_flag = sph_flag = 0; molecule_flag = q_flag = mu_flag = 0; @@ -185,6 +186,8 @@ Atom::~Atom() memory->destroy(s0); memory->destroy(x0); memory->destroy(ellipsoid); + memory->destroy(line); + memory->destroy(tri); memory->destroy(spin); memory->destroy(eradius); memory->destroy(ervel); @@ -259,8 +262,9 @@ void Atom::create_avec(const char *style, int narg, char **arg, char *suffix) // may have been set by old avec // customize by adding new flag - sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0; - + sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0; + peri_flag = electron_flag = 0; + molecule_flag = q_flag = mu_flag = 0; rmass_flag = radius_flag = omega_flag = torque_flag = angmom_flag = 0; vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0; diff --git a/src/atom.h b/src/atom.h index 98b687ec9a..429aacb1c2 100644 --- a/src/atom.h +++ b/src/atom.h @@ -51,7 +51,7 @@ class Atom : protected Pointers { double **omega,**angmom,**torque; double *radius,*rmass,*vfrac,*s0; double **x0; - int *ellipsoid; + int *ellipsoid,*line,*tri; int *spin; double *eradius,*ervel,*erforce,*ervelforce; double *cs,*csforce,*vforce; @@ -84,7 +84,7 @@ class Atom : protected Pointers { // atom style and per-atom array existence flags // customize by adding new flag - int sphere_flag,ellipsoid_flag,peri_flag,electron_flag; + int sphere_flag,ellipsoid_flag,line_flag,tri_flag,peri_flag,electron_flag; int wavepacket_flag,sph_flag; int molecule_flag,q_flag,mu_flag; diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index f7605d5552..80efd8a5bf 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -11,10 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "math.h" #include "string.h" #include "compute_property_atom.h" +#include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "update.h" #include "domain.h" #include "memory.h" @@ -173,39 +177,39 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) @@ -244,6 +248,83 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_erforce; + } else if (strcmp(arg[iarg],"end1x") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1x; + } else if (strcmp(arg[iarg],"end1y") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1y; + } else if (strcmp(arg[iarg],"end1z") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1z; + } else if (strcmp(arg[iarg],"end2x") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2x; + } else if (strcmp(arg[iarg],"end2y") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2y; + } else if (strcmp(arg[iarg],"end2z") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2z; + + } else if (strcmp(arg[iarg],"corner1x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1x; + } else if (strcmp(arg[iarg],"corner1y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1y; + } else if (strcmp(arg[iarg],"corner1z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1z; + } else if (strcmp(arg[iarg],"corner2x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2x; + } else if (strcmp(arg[iarg],"corner2y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2y; + } else if (strcmp(arg[iarg],"corner2z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2z; + } else if (strcmp(arg[iarg],"corner3x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3x; + } else if (strcmp(arg[iarg],"corner3y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3y; + } else if (strcmp(arg[iarg],"corner3z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3z; + } else error->all(FLERR,"Invalid keyword in compute property/atom command"); } @@ -994,7 +1075,7 @@ void ComputePropertyAtom::pack_angmomz(int n) void ComputePropertyAtom::pack_shapex(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1011,7 +1092,7 @@ void ComputePropertyAtom::pack_shapex(int n) void ComputePropertyAtom::pack_shapey(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1028,7 +1109,7 @@ void ComputePropertyAtom::pack_shapey(int n) void ComputePropertyAtom::pack_shapez(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1045,7 +1126,7 @@ void ComputePropertyAtom::pack_shapez(int n) void ComputePropertyAtom::pack_quatw(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1062,7 +1143,7 @@ void ComputePropertyAtom::pack_quatw(int n) void ComputePropertyAtom::pack_quati(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1079,7 +1160,7 @@ void ComputePropertyAtom::pack_quati(int n) void ComputePropertyAtom::pack_quatj(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1096,7 +1177,7 @@ void ComputePropertyAtom::pack_quatj(int n) void ComputePropertyAtom::pack_quatk(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1213,3 +1294,294 @@ void ComputePropertyAtom::pack_erforce(int n) n += nvalues; } } + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1x(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][0] - 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1y(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][1] - 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1z(int n) +{ + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = x[i][2]; + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2x(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][0] + 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2y(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][1] + 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2z(int n) +{ + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = x[i][2]; + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index b32d0a93df..8f675b6204 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -38,7 +38,9 @@ class ComputePropertyAtom : public Compute { double *vector; double **array; double *buf; - class AtomVecEllipsoid *avec; + class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; typedef void (ComputePropertyAtom::*FnPtrPack)(int); FnPtrPack *pack_choice; // ptrs to pack functions @@ -101,6 +103,21 @@ class ComputePropertyAtom : public Compute { void pack_eradius(int); void pack_ervel(int); void pack_erforce(int); + void pack_end1x(int); + void pack_end1y(int); + void pack_end1z(int); + void pack_end2x(int); + void pack_end2y(int); + void pack_end2z(int); + void pack_corner1x(int); + void pack_corner1y(int); + void pack_corner1z(int); + void pack_corner2x(int); + void pack_corner2y(int); + void pack_corner2z(int); + void pack_corner3x(int); + void pack_corner3y(int); + void pack_corner3z(int); }; } diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp index cf63dfa116..63df87b782 100644 --- a/src/fix_rigid.cpp +++ b/src/fix_rigid.cpp @@ -19,6 +19,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "domain.h" #include "update.h" #include "respa.h" @@ -28,14 +30,20 @@ #include "random_mars.h" #include "force.h" #include "output.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 1.0e-6 #define EPSILON 1.0e-7 +#define SINERTIA 0.4 // moment of inertia prefactor for sphere +#define EINERTIA 0.4 // moment of inertia prefactor for ellipsoid +#define LINERTIA (1.0/12.0) // moment of inertia prefactor for line segment + /* ---------------------------------------------------------------------- */ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : @@ -56,12 +64,12 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // perform initial allocation of atom-based arrays // register with Atom class - extended = dorientflag = qorientflag = 0; + extended = orientflag = dorientflag = 0; body = NULL; displace = NULL; eflags = NULL; + orient = NULL; dorient = NULL; - qorient = NULL; grow_arrays(atom->nmax); atom->add_callback(0); @@ -278,7 +286,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : else error->all(FLERR,"Illegal fix rigid command"); if (domain->dimension == 2 && (xflag == 1.0 || yflag == 1.0)) - error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation"); + error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation"); int count = 0; for (int m = mlo; m <= mhi; m++) { @@ -384,18 +392,24 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // bitmasks for properties of extended particles - INERTIA_POINT = 1; - INERTIA_SPHERE = 2; - INERTIA_ELLIPSOID = 4; - ORIENT_DIPOLE = 8; - ORIENT_QUAT = 16; - OMEGA = 32; - ANGMOM = 64; - TORQUE = 128; + POINT = 1; + SPHERE = 2; + ELLIPSOID = 4; + LINE = 8; + TRIANGLE = 16; + DIPOLE = 32; + OMEGA = 64; + ANGMOM = 128; + TORQUE = 256; + + MINUSPI = -MY_PI; + TWOPI = 2.0*MY_PI; // atom style pointers to particles that store extra info avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); // print statistics @@ -423,8 +437,8 @@ FixRigid::~FixRigid() memory->destroy(body); memory->destroy(displace); memory->destroy(eflags); + memory->destroy(orient); memory->destroy(dorient); - memory->destroy(qorient); // delete nbody-length arrays @@ -469,7 +483,7 @@ int FixRigid::setmask() void FixRigid::init() { - int i,ibody; + int i,itype,ibody; triclinic = domain->triclinic; @@ -504,24 +518,33 @@ void FixRigid::init() // extended = 1 if any particle in a rigid body is finite size // or has a dipole moment - extended = dorientflag = qorientflag = 0; + extended = orientflag = dorientflag = 0; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **mu = atom->mu; double *radius = atom->radius; double *rmass = atom->rmass; double *mass = atom->mass; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *type = atom->type; int nlocal = atom->nlocal; - if (atom->radius_flag || atom->ellipsoid_flag || atom->mu_flag) { + if (atom->radius_flag || atom->ellipsoid_flag || atom->line_flag || + atom->tri_flag || atom->mu_flag) { int flag = 0; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; if (radius && radius[i] > 0.0) flag = 1; if (ellipsoid && ellipsoid[i] >= 0) flag = 1; + if (line && line[i] >= 0) flag = 1; + if (tri && tri[i] >= 0) flag = 1; if (mu && mu[i][3] > 0.0) flag = 1; } @@ -529,35 +552,45 @@ void FixRigid::init() } // grow extended arrays and set extended flags for each particle - // qorientflag = 1 if any particle stores quat orientation + // orientflag = 4 if any particle stores ellipsoid or tri orientation + // orientflag = 1 if any particle stores line orientation // dorientflag = 1 if any particle stores dipole orientation if (extended) { + if (atom->ellipsoid_flag) orientflag = 4; + if (atom->line_flag) orientflag = 1; + if (atom->tri_flag) orientflag = 4; if (atom->mu_flag) dorientflag = 1; - if (atom->ellipsoid_flag) qorientflag = 1; grow_arrays(atom->nmax); for (i = 0; i < nlocal; i++) { eflags[i] = 0; if (body[i] < 0) continue; - // set INERTIA to POINT or SPHERE or ELLIPSOID + // set to POINT or SPHERE or ELLIPSOID or LINE if (radius && radius[i] > 0.0) { - eflags[i] |= INERTIA_SPHERE; + eflags[i] |= SPHERE; eflags[i] |= OMEGA; eflags[i] |= TORQUE; } else if (ellipsoid && ellipsoid[i] >= 0) { - eflags[i] |= INERTIA_ELLIPSOID; - eflags[i] |= ORIENT_QUAT; + eflags[i] |= ELLIPSOID; eflags[i] |= ANGMOM; eflags[i] |= TORQUE; - } else eflags[i] |= INERTIA_POINT; + } else if (line && line[i] >= 0) { + eflags[i] |= LINE; + eflags[i] |= OMEGA; + eflags[i] |= TORQUE; + } else if (tri && tri[i] >= 0) { + eflags[i] |= TRIANGLE; + eflags[i] |= ANGMOM; + eflags[i] |= TORQUE; + } else eflags[i] |= POINT; // set DIPOLE if atom->mu and mu[3] > 0.0 if (atom->mu_flag && mu[i][3] > 0.0) - eflags[i] |= ORIENT_DIPOLE; + eflags[i] |= DIPOLE; } } @@ -592,8 +625,8 @@ void FixRigid::init() if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) || (zbox && !periodicity[2])) - error->one(FLERR,"Fix rigid atom has non-zero image flag " - "in a non-periodic dimension"); + error->one(FLERR,"Fix rigid atom has non-zero image flag " + "in a non-periodic dimension"); if (triclinic == 0) { xunwrap = x[i][0] + xbox*xprd; @@ -629,7 +662,7 @@ void FixRigid::init() // dx,dy,dz = coords relative to center-of-mass // symmetric 3x3 inertia tensor stored in Voigt notation as 6-vector - double dx,dy,dz; + double dx,dy,dz,rad; for (ibody = 0; ibody < nbody; ibody++) for (i = 0; i < 6; i++) sum[ibody][i] = 0.0; @@ -671,18 +704,19 @@ void FixRigid::init() if (extended) { double ivec[6]; - double *shape,*quatatom; + double *shape,*quatatom,*inertiaatom; + double length,theta; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; massone = rmass[i]; - if (eflags[i] & INERTIA_SPHERE) { - sum[ibody][0] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][1] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][2] += 0.4 * massone * radius[i]*radius[i]; - } else if (eflags[i] & INERTIA_ELLIPSOID) { + if (eflags[i] & SPHERE) { + sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i]; + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; MathExtra::inertia_ellipsoid(shape,quatatom,massone,ivec); @@ -692,6 +726,26 @@ void FixRigid::init() sum[ibody][3] += ivec[3]; sum[ibody][4] += ivec[4]; sum[ibody][5] += ivec[5]; + } else if (eflags[i] & LINE) { + length = lbonus[line[i]].length; + theta = lbonus[line[i]].theta; + MathExtra::inertia_line(length,theta,massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::inertia_triangle(inertiaatom,quatatom,massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; } } } @@ -715,7 +769,8 @@ void FixRigid::init() tensor[0][1] = tensor[1][0] = all[ibody][5]; ierror = MathExtra::jacobi(tensor,inertia[ibody],evectors); - if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for rigid body"); + if (ierror) error->all(FLERR, + "Insufficient Jacobi rotations for rigid body"); ex_space[ibody][0] = evectors[0][0]; ex_space[ibody][1] = evectors[1][0]; @@ -756,6 +811,7 @@ void FixRigid::init() double qc[4],delta[3]; double *quatatom; + double theta_body; for (i = 0; i < nlocal; i++) { if (body[i] < 0) { @@ -786,20 +842,34 @@ void FixRigid::init() ez_space[ibody],delta,displace[i]); if (extended) { - if (eflags[i] & ORIENT_DIPOLE) { + if (eflags[i] & ELLIPSOID) { + quatatom = ebonus[ellipsoid[i]].quat; + MathExtra::qconjugate(quat[ibody],qc); + MathExtra::quatquat(qc,quatatom,orient[i]); + MathExtra::qnormalize(orient[i]); + } else if (eflags[i] & LINE) { + if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]); + else theta_body = -2.0*acos(quat[ibody][0]); + orient[i][0] = lbonus[line[i]].theta - theta_body; + while (orient[i][0] <= MINUSPI) orient[i][0] += TWOPI; + while (orient[i][0] > MY_PI) orient[i][0] -= TWOPI; + if (orientflag == 4) orient[i][1] = orient[i][2] = orient[i][3] = 0.0; + } else if (eflags[i] & TRIANGLE) { + quatatom = tbonus[tri[i]].quat; + MathExtra::qconjugate(quat[ibody],qc); + MathExtra::quatquat(qc,quatatom,orient[i]); + MathExtra::qnormalize(orient[i]); + } else if (orientflag == 4) { + orient[i][0] = orient[i][1] = orient[i][2] = orient[i][3] = 0.0; + } else if (orientflag == 1) + orient[i][0] = 0.0; + + if (eflags[i] & DIPOLE) { MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody], ez_space[ibody],mu[i],dorient[i]); MathExtra::snormalize3(mu[i][3],dorient[i],dorient[i]); } else if (dorientflag) dorient[i][0] = dorient[i][1] = dorient[i][2] = 0.0; - - if (eflags[i] & ORIENT_QUAT) { - quatatom = ebonus[ellipsoid[i]].quat; - MathExtra::qconjugate(quat[ibody],qc); - MathExtra::quatquat(qc,quatatom,qorient[i]); - MathExtra::qnormalize(qorient[i]); - } else if (qorientflag) - qorient[i][0] = qorient[i][1] = qorient[i][2] = qorient[i][3] = 0.0; } } @@ -831,20 +901,39 @@ void FixRigid::init() if (extended) { double ivec[6]; - double *shape; + double *shape,*inertiaatom; + double length; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; massone = rmass[i]; - if (eflags[i] & INERTIA_SPHERE) { - sum[ibody][0] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][1] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][2] += 0.4 * massone * radius[i]*radius[i]; - } else if (eflags[i] & INERTIA_ELLIPSOID) { + if (eflags[i] & SPHERE) { + sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i]; + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; - MathExtra::inertia_ellipsoid(shape,qorient[i],massone,ivec); + MathExtra::inertia_ellipsoid(shape,orient[i],massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & LINE) { + length = lbonus[line[i]].length; + MathExtra::inertia_line(length,orient[i][0],massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + MathExtra::inertia_triangle(inertiaatom,orient[i],massone,ivec); sum[ibody][0] += ivec[0]; sum[ibody][1] += ivec[1]; sum[ibody][2] += ivec[2]; @@ -894,7 +983,8 @@ void FixRigid::init() ndof += fflag[ibody][0] + fflag[ibody][1] + fflag[ibody][2]; ndof += tflag[ibody][0] + tflag[ibody][1] + tflag[ibody][2]; } - tfactor = force->mvv2e / (ndof * force->boltz); + if (ndof > 0.0) tfactor = force->mvv2e / (ndof * force->boltz); + else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ @@ -996,24 +1086,29 @@ void FixRigid::setup(int vflag) // extended particles add their rotation/torque to angmom/torque of body if (extended) { + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; double **torque_one = atom->torque; double *radius = atom->radius; + int *line = atom->line; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; if (eflags[i] & OMEGA) { - if (rmass) massone = rmass[i]; - else massone = mass[type[i]]; - radone = radius[i]; - sum[ibody][0] += 0.4 * massone * radone*radone * omega_one[i][0]; - sum[ibody][1] += 0.4 * massone * radone*radone * omega_one[i][1]; - sum[ibody][2] += 0.4 * massone * radone*radone * omega_one[i][2]; + if (eflags[i] & SPHERE) { + radone = radius[i]; + sum[ibody][0] += SINERTIA*rmass[i] * radone*radone * omega_one[i][0]; + sum[ibody][1] += SINERTIA*rmass[i] * radone*radone * omega_one[i][1]; + sum[ibody][2] += SINERTIA*rmass[i] * radone*radone * omega_one[i][2]; + } else if (eflags[i] & LINE) { + radone = lbonus[line[i]].length; + sum[ibody][2] += LINERTIA*rmass[i] * radone*radone * omega_one[i][2]; + } } - if (eflags[i] & ANGMOM) { sum[ibody][0] += angmom_one[i][0]; sum[ibody][1] += angmom_one[i][1]; @@ -1516,7 +1611,7 @@ void FixRigid::deform(int flag) void FixRigid::set_xv() { - int ibody; + int ibody,itype; int xbox,ybox,zbox; double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone; double xy,xz,yz; @@ -1622,43 +1717,64 @@ void FixRigid::set_xv() // set orientation, omega, angmom of each extended particle if (extended) { - double *shape,*quatatom; + double theta_body,theta; + double *shape,*quatatom,*inertiaatom; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; double **mu = atom->mu; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; for (int i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; - - if (eflags[i] & ORIENT_DIPOLE) { - MathExtra::quat_to_mat(quat[ibody],p); - MathExtra::matvec(p,dorient[i],mu[i]); - MathExtra::snormalize3(mu[i][3],mu[i],mu[i]); - } - if (eflags[i] & ORIENT_QUAT) { - quatatom = ebonus[ellipsoid[i]].quat; - MathExtra::quatquat(quat[ibody],qorient[i],quatatom); - MathExtra::qnormalize(quatatom); - } - if (eflags[i] & OMEGA) { + + if (eflags[i] & SPHERE) { omega_one[i][0] = omega[ibody][0]; omega_one[i][1] = omega[ibody][1]; omega_one[i][2] = omega[ibody][2]; - } - if (eflags[i] & ANGMOM) { + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; - ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); - ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); - ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); + MathExtra::quatquat(quat[ibody],orient[i],quatatom); + MathExtra::qnormalize(quatatom); + ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); + ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); + ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione, angmom_one[i]); + } else if (eflags[i] & LINE) { + if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]); + else theta_body = -2.0*acos(quat[ibody][0]); + theta = orient[i][0] + theta_body; + while (theta <= MINUSPI) theta += TWOPI; + while (theta > MY_PI) theta -= TWOPI; + lbonus[line[i]].theta = theta; + omega_one[i][0] = omega[ibody][0]; + omega_one[i][1] = omega[ibody][1]; + omega_one[i][2] = omega[ibody][2]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::quatquat(quat[ibody],orient[i],quatatom); + MathExtra::qnormalize(quatatom); + MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); + MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone, + inertiaatom,angmom_one[i]); + } + if (eflags[i] & DIPOLE) { + MathExtra::quat_to_mat(quat[ibody],p); + MathExtra::matvec(p,dorient[i],mu[i]); + MathExtra::snormalize3(mu[i][3],mu[i],mu[i]); } } } @@ -1672,8 +1788,9 @@ void FixRigid::set_xv() void FixRigid::set_v() { - int ibody; + int ibody,itype; int xbox,ybox,zbox; + double dx,dy,dz; double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone; double xy,xz,yz; double ione[3],exone[3],eyone[3],ezone[3],delta[3],vr[6]; @@ -1761,32 +1878,44 @@ void FixRigid::set_v() // set omega, angmom of each extended particle if (extended) { - double *shape,*quatatom; + double *shape,*quatatom,*inertiaatom; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; int *ellipsoid = atom->ellipsoid; + int *tri = atom->tri; for (int i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; - if (eflags[i] & OMEGA) { + if (eflags[i] & SPHERE) { omega_one[i][0] = omega[ibody][0]; omega_one[i][1] = omega[ibody][1]; omega_one[i][2] = omega[ibody][2]; - } - if (eflags[i] & ANGMOM) { + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; - ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); - ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); - ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); + ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); + ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); + ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione, angmom_one[i]); + } else if (eflags[i] & LINE) { + omega_one[i][0] = omega[ibody][0]; + omega_one[i][1] = omega[ibody][1]; + omega_one[i][2] = omega[ibody][2]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); + MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone, + inertiaatom,angmom_one[i]); } } } @@ -1804,8 +1933,8 @@ double FixRigid::memory_usage() bytes += maxvatom*6 * sizeof(double); if (extended) { bytes += nmax * sizeof(int); + if (orientflag) bytes = nmax*orientflag * sizeof(double); if (dorientflag) bytes = nmax*3 * sizeof(double); - if (qorientflag) bytes = nmax*4 * sizeof(double); } return bytes; } @@ -1820,8 +1949,8 @@ void FixRigid::grow_arrays(int nmax) memory->grow(displace,nmax,3,"rigid:displace"); if (extended) { memory->grow(eflags,nmax,"rigid:eflags"); + if (orientflag) memory->grow(orient,nmax,orientflag,"rigid:orient"); if (dorientflag) memory->grow(dorient,nmax,3,"rigid:dorient"); - if (qorientflag) memory->grow(qorient,nmax,4,"rigid:qorient"); } } @@ -1837,17 +1966,13 @@ void FixRigid::copy_arrays(int i, int j) displace[j][2] = displace[i][2]; if (extended) { eflags[j] = eflags[i]; + for (int k = 0; k < orientflag; k++) + orient[j][k] = orient[i][k]; if (dorientflag) { dorient[j][0] = dorient[i][0]; dorient[j][1] = dorient[i][1]; dorient[j][2] = dorient[i][2]; } - if (qorientflag) { - qorient[j][0] = qorient[i][0]; - qorient[j][1] = qorient[i][1]; - qorient[j][2] = qorient[i][2]; - qorient[j][3] = qorient[i][3]; - } } } @@ -1877,17 +2002,13 @@ int FixRigid::pack_exchange(int i, double *buf) int m = 4; buf[m++] = eflags[i]; + for (int j = 0; j < orientflag; j++) + buf[m++] = orient[i][j]; if (dorientflag) { buf[m++] = dorient[i][0]; buf[m++] = dorient[i][1]; buf[m++] = dorient[i][2]; } - if (qorientflag) { - buf[m++] = qorient[i][0]; - buf[m++] = qorient[i][1]; - buf[m++] = qorient[i][2]; - buf[m++] = qorient[i][3]; - } return m; } @@ -1905,17 +2026,13 @@ int FixRigid::unpack_exchange(int nlocal, double *buf) int m = 4; eflags[nlocal] = static_cast (buf[m++]); + for (int j = 0; j < orientflag; j++) + orient[nlocal][j] = buf[m++]; if (dorientflag) { dorient[nlocal][0] = buf[m++]; dorient[nlocal][1] = buf[m++]; dorient[nlocal][2] = buf[m++]; } - if (qorientflag) { - qorient[nlocal][0] = buf[m++]; - qorient[nlocal][1] = buf[m++]; - qorient[nlocal][2] = buf[m++]; - qorient[nlocal][3] = buf[m++]; - } return m; } diff --git a/src/fix_rigid.h b/src/fix_rigid.h index 06121ad47a..fa803df5f7 100644 --- a/src/fix_rigid.h +++ b/src/fix_rigid.h @@ -56,6 +56,7 @@ class FixRigid : public Fix { double dtv,dtf,dtq; double *step_respa; int triclinic; + double MINUSPI,TWOPI; int nbody; // # of rigid bodies int *nrigid; // # of atoms in each rigid body @@ -82,11 +83,11 @@ class FixRigid : public Fix { int **remapflag; // PBC remap flags for each rigid body int extended; // 1 if any particles have extended attributes + int orientflag; // 1 if particles store spatial orientation int dorientflag; // 1 if particles store dipole orientation - int qorientflag; // 1 if particles store quat orientation int *eflags; // flags for extended particles - double **qorient; // rotation state of ext particle wrt rigid body + double **orient; // orientation vector of particle wrt rigid body double **dorient; // orientation of dipole mu wrt rigid body double tfactor; // scale factor on temperature of rigid bodies @@ -104,10 +105,10 @@ class FixRigid : public Fix { class RanMars *random; class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; - // bitmasks for eflags - int INERTIA_POINT,INERTIA_SPHERE,INERTIA_ELLIPSOID; - int ORIENT_DIPOLE,ORIENT_QUAT; + int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags int OMEGA,ANGMOM,TORQUE; void no_squish_rotate(int, double *, double *, double *, double); diff --git a/src/read_data.cpp b/src/read_data.cpp index a5a5e47ccb..772c3a3824 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -21,6 +21,8 @@ #include "atom.h" #include "atom_vec.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "comm.h" #include "update.h" #include "force.h" @@ -42,7 +44,10 @@ using namespace LAMMPS_NS; #define DELTA 4 // must be 2 or larger // customize for new sections -#define NSECTIONS 21 // change when add to header::section_keywords +#define NSECTIONS 23 // change when add to header::section_keywords + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) /* ---------------------------------------------------------------------- */ @@ -60,6 +65,10 @@ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp) nellipsoids = 0; avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + nlines = 0; + avec_line = (AtomVecLine *) atom->style_match("line"); + ntris = 0; + avec_tri = (AtomVecTri *) atom->style_match("tri"); } /* ---------------------------------------------------------------------- */ @@ -151,7 +160,17 @@ void ReadData::command(int narg, char **arg) if (!avec_ellipsoid) error->all(FLERR,"Invalid data file section: Ellipsoids"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids"); - ellipsoids(); + bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids"); + } else if (strcmp(keyword,"Lines") == 0) { + if (!avec_line) + error->all(FLERR,"Invalid data file section: Lines"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines"); + bonus(nlines,(AtomVec *) avec_line,"lines"); + } else if (strcmp(keyword,"Triangles") == 0) { + if (!avec_tri) + error->all(FLERR,"Invalid data file section: Triangles"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles"); + bonus(ntris,(AtomVec *) avec_tri,"triangles"); } else if (strcmp(keyword,"Bonds") == 0) { if (atom->avec->bonds_allow == 0) @@ -222,25 +241,31 @@ void ReadData::command(int narg, char **arg) if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before " + "MiddleBondTorsion Coeffs"); dihedralcoeffs(1); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before EndBondTorsion Coeffs"); dihedralcoeffs(2); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before AngleTorsion Coeffs"); dihedralcoeffs(3); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before " + "AngleAngleTorsion Coeffs"); dihedralcoeffs(4); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) @@ -274,7 +299,8 @@ void ReadData::command(int narg, char **arg) // error if natoms > 0 yet no atoms were read - if (atom->natoms > 0 && atomflag == 0) error->all(FLERR,"No atoms in data file"); + if (atom->natoms > 0 && atomflag == 0) + error->all(FLERR,"No atoms in data file"); // create bond topology now that system is defined @@ -303,7 +329,7 @@ void ReadData::header(int flag) // customize for new sections char *section_keywords[NSECTIONS] = - {"Atoms","Velocities","Ellipsoids", + {"Atoms","Velocities","Ellipsoids","Lines","Triangles", "Bonds","Angles","Dihedrals","Impropers", "Masses","Pair Coeffs","Bond Coeffs","Angle Coeffs", "Dihedral Coeffs","Improper Coeffs", @@ -373,6 +399,14 @@ void ReadData::header(int flag) if (!avec_ellipsoid) error->all(FLERR,"No ellipsoids allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nellipsoids); + } else if (strstr(line,"lines")) { + if (!avec_line) + error->all(FLERR,"No lines allowed with this atom style"); + sscanf(line,BIGINT_FORMAT,&nlines); + } else if (strstr(line,"triangles")) { + if (!avec_tri) + error->all(FLERR,"No triangles allowed with this atom style"); + sscanf(line,BIGINT_FORMAT,&ntris); } else if (strstr(line,"xlo xhi")) @@ -475,7 +509,8 @@ void ReadData::atoms() if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } - if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); + if (natoms != atom->natoms) + error->all(FLERR,"Did not assign all atoms correctly"); // if any atom ID < 0, error // if all atom IDs = 0, tag_enable = 0 @@ -568,11 +603,11 @@ void ReadData::velocities() } /* ---------------------------------------------------------------------- - read all ellipsoids + read all bonus data to find atoms, must build atom map if not a molecular system ------------------------------------------------------------------------- */ -void ReadData::ellipsoids() +void ReadData::bonus(bigint nbonus, AtomVec *ptr, char *type) { int i,m,nchunk; @@ -585,7 +620,7 @@ void ReadData::ellipsoids() } bigint nread = 0; - bigint natoms = nellipsoids; + bigint natoms = nbonus; while (nread < natoms) { if (natoms-nread > CHUNK) nchunk = CHUNK; @@ -603,7 +638,7 @@ void ReadData::ellipsoids() MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); - atom->data_bonus(nchunk,buffer,avec_ellipsoid); + atom->data_bonus(nchunk,buffer,ptr); nread += nchunk; } @@ -613,8 +648,8 @@ void ReadData::ellipsoids() } if (me == 0) { - if (screen) fprintf(screen," " BIGINT_FORMAT " ellipsoids\n",natoms); - if (logfile) fprintf(logfile," " BIGINT_FORMAT " ellipsoids\n",natoms); + if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type); + if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type); } } @@ -660,7 +695,8 @@ void ReadData::bonds() if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor); } - if (sum != factor*atom->nbonds) error->all(FLERR,"Bonds assigned incorrectly"); + if (sum != factor*atom->nbonds) + error->all(FLERR,"Bonds assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -705,7 +741,8 @@ void ReadData::angles() if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor); } - if (sum != factor*atom->nangles) error->all(FLERR,"Angles assigned incorrectly"); + if (sum != factor*atom->nangles) + error->all(FLERR,"Angles assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -1010,6 +1047,8 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, int natoms = static_cast (atom->natoms); bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0; int ellipsoid_flag = 0; + int line_flag = 0; + int tri_flag = 0; // customize for new sections // allocate topology counting vector @@ -1031,6 +1070,14 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, error->all(FLERR,"Invalid data file section: Ellipsoids"); ellipsoid_flag = 1; skip_lines(nellipsoids); + } else if (strcmp(keyword,"Lines") == 0) { + if (!avec_line) error->all(FLERR,"Invalid data file section: Lines"); + line_flag = 1; + skip_lines(nlines); + } else if (strcmp(keyword,"Triangles") == 0) { + if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles"); + tri_flag = 1; + skip_lines(ntris); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) @@ -1077,25 +1124,31 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before " + "MiddleBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before EndBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before AngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->all(FLERR, + "Must define dihedral_style before " + "AngleAngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) @@ -1252,6 +1305,10 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (nellipsoids && !ellipsoid_flag) error->one(FLERR,"Needed bonus data not in data file"); + if (nlines && !line_flag) + error->one(FLERR,"Needed bonus data not in data file"); + if (ntris && !tri_flag) + error->one(FLERR,"Needed bonus data not in data file"); } /* ---------------------------------------------------------------------- diff --git a/src/read_data.h b/src/read_data.h index 80fd441413..67398469c5 100644 --- a/src/read_data.h +++ b/src/read_data.h @@ -40,6 +40,10 @@ class ReadData : protected Pointers { bigint nellipsoids; class AtomVecEllipsoid *avec_ellipsoid; + bigint nlines; + class AtomVecLine *avec_line; + bigint ntris; + class AtomVecTri *avec_tri; void open(char *); void scan(int &, int &, int &, int &); @@ -51,7 +55,7 @@ class ReadData : protected Pointers { void atoms(); void velocities(); - void ellipsoids(); + void bonus(bigint, class AtomVec *, char *); void bonds(); void angles(); diff --git a/src/set.cpp b/src/set.cpp index 4e76dfa2b4..2a4c25731b 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -19,6 +19,8 @@ #include "atom.h" #include "atom_vec.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "domain.h" #include "region.h" #include "group.h" @@ -35,8 +37,8 @@ using namespace LAMMPS_NS; using namespace MathConst; enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT}; -enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE, - DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM, +enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI, + DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,ANGMOM, DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, MESO_E,MESO_CV,MESO_RHO}; @@ -150,6 +152,22 @@ void Set::command(int narg, char **arg) } set(SHAPE); iarg += 4; + } else if (strcmp(arg[iarg],"length") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + if (!atom->line_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command"); + set(LENGTH); + iarg += 2; + } else if (strcmp(arg[iarg],"tri") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + if (!atom->tri_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command"); + set(TRI); + iarg += 2; } else if (strcmp(arg[iarg],"dipole") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); xvalue = atof(arg[iarg+1]); @@ -177,19 +195,36 @@ void Set::command(int narg, char **arg) yvalue = atof(arg[iarg+2]); zvalue = atof(arg[iarg+3]); wvalue = atof(arg[iarg+4]); - if (!atom->ellipsoid_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); set(QUAT); iarg += 5; } else if (strcmp(arg[iarg],"quat/random") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); - if (!atom->ellipsoid_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; + } else if (strcmp(arg[iarg],"theta") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + dvalue *= MY_PI/180.0; + if (!atom->line_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + set(THETA); + iarg += 2; + } else if (strcmp(arg[iarg],"angmom") == 0) { + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + xvalue = atof(arg[iarg+1]); + yvalue = atof(arg[iarg+2]); + zvalue = atof(arg[iarg+3]); + if (!atom->ellipsoid_flag && !atom->tri_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + set(ANGMOM); + iarg += 4; } else if (strcmp(arg[iarg],"diameter") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); @@ -385,6 +420,8 @@ void Set::set(int keyword) { AtomVecEllipsoid *avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line"); + AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri"); selection(atom->nlocal); @@ -405,23 +442,49 @@ void Set::set(int keyword) else if (keyword == MESO_CV) atom->cv[i] = dvalue; else if (keyword == MESO_RHO) atom->rho[i] = dvalue; - // set shape + // set shape of ellipsoidal particle else if (keyword == SHAPE) avec_ellipsoid->set_shape(i,0.5*xvalue,0.5*yvalue,0.5*zvalue); + // set length of line particle + + else if (keyword == LENGTH) + avec_line->set_length(i,dvalue); + + // set corners of tri particle + + else if (keyword == TRI) + avec_tri->set_equilateral(i,dvalue); + // set rmass via density // if radius > 0.0, treat as sphere // if shape > 0.0, treat as ellipsoid + // if length > 0.0, treat as line + // if area > 0.0, treat as tri // else set rmass to density directly else if (keyword == DENSITY) { if (atom->radius_flag && atom->radius[i] > 0.0) - atom->rmass[i] = 4.0*MY_PI*THIRD * + atom->rmass[i] = 4.0*MY_PI/3.0 * atom->radius[i]*atom->radius[i]*atom->radius[i] * dvalue; else if (atom->ellipsoid_flag && atom->ellipsoid[i] >= 0) { double *shape = avec_ellipsoid->bonus[atom->ellipsoid[i]].shape; - atom->rmass[i] = 4.0*MY_PI*THIRD * shape[0]*shape[1]*shape[2] * dvalue; + atom->rmass[i] = 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2] * dvalue; + } else if (atom->line_flag && atom->line[i] >= 0) { + double length = avec_line->bonus[atom->line[i]].length; + atom->rmass[i] = length * dvalue; + } else if (atom->tri_flag && atom->tri[i] >= 0) { + double *c1 = avec_tri->bonus[atom->tri[i]].c1; + double *c2 = avec_tri->bonus[atom->tri[i]].c2; + double *c3 = avec_tri->bonus[atom->tri[i]].c3; + double c2mc1[2],c3mc1[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + double norm[3]; + MathExtra::cross3(c2mc1,c3mc1,norm); + double area = 0.5 * MathExtra::len3(norm); + atom->rmass[i] = area * dvalue; } else atom->rmass[i] = dvalue; // reset any or all of 3 image flags @@ -446,13 +509,17 @@ void Set::set(int keyword) mu[i][3] = sqrt(mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]); - // set quaternion orientation + // set quaternion orientation of ellipsoid or tri particle } else if (keyword == QUAT) { - if (atom->ellipsoid[i] < 0) - error->one(FLERR, - "Cannot set quaternion for atom that is not an ellipsoid"); - double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + double *quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else if (avec_tri && atom->tri[i] >= 0) + quat = avec_tri->bonus[atom->tri[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + double theta2 = MY_PI2 * wvalue/180.0; double sintheta2 = sin(theta2); quat[0] = cos(theta2); @@ -460,7 +527,22 @@ void Set::set(int keyword) quat[2] = yvalue * sintheta2; quat[3] = zvalue * sintheta2; MathExtra::qnormalize(quat); + + // set theta of line particle + + } else if (keyword == THETA) { + if (atom->line[i] < 0) + error->one(FLERR,"Cannot set theta for atom that is not a line"); + avec_line->bonus[atom->line[i]].theta = dvalue; + + // set angmom of ellipsoidal or tri particle + + } else if (keyword == ANGMOM) { + atom->angmom[i][0] = xvalue; + atom->angmom[i][1] = yvalue; + atom->angmom[i][2] = zvalue; } + count++; } } @@ -475,6 +557,11 @@ void Set::setrandom(int keyword) { int i; + AtomVecEllipsoid *avec_ellipsoid = + (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line"); + AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri"); + selection(atom->nlocal); RanPark *random = new RanPark(lmp,1); double **x = atom->x; @@ -535,13 +622,10 @@ void Set::setrandom(int keyword) } // set quaternions to random orientations in 3d or 2d - // no need to normalize quats since creations algorithms already do } else if (keyword == QUAT_RANDOM) { - AtomVecEllipsoid *avec_ellipsoid = - (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; + int *tri = atom->tri; int nlocal = atom->nlocal; double *quat; @@ -549,10 +633,13 @@ void Set::setrandom(int keyword) double s,t1,t2,theta1,theta2; for (i = 0; i < nlocal; i++) if (select[i]) { - if (ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom " - "that is not an ellipsoid"); - quat = bonus[ellipsoid[i]].quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else if (avec_tri && atom->tri[i] >= 0) + quat = avec_tri->bonus[atom->tri[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + random->reset(seed,x[i]); s = random->uniform(); t1 = sqrt(1.0-s); @@ -570,10 +657,11 @@ void Set::setrandom(int keyword) double theta2; for (i = 0; i < nlocal; i++) if (select[i]) { - if (ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom " - "that is not an ellipsoid"); - quat = bonus[ellipsoid[i]].quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + random->reset(seed,x[i]); theta2 = MY_PI*random->uniform(); quat[0] = cos(theta2); From c6d228775fc0b5d9aa433893f38c3f6083d2db05 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 14:58:00 +0000 Subject: [PATCH 210/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7147 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/atom_vec_line.cpp | 1167 ++++++++++++++++++++++++++++++ src/atom_vec_line.h | 96 +++ src/atom_vec_tri.cpp | 1561 +++++++++++++++++++++++++++++++++++++++++ src/atom_vec_tri.h | 97 +++ 4 files changed, 2921 insertions(+) create mode 100644 src/atom_vec_line.cpp create mode 100644 src/atom_vec_line.h create mode 100644 src/atom_vec_tri.cpp create mode 100644 src/atom_vec_tri.h diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp new file mode 100644 index 0000000000..ebf8b7d7a8 --- /dev/null +++ b/src/atom_vec_line.cpp @@ -0,0 +1,1167 @@ +/* ---------------------------------------------------------------------- + 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 "lmptype.h" +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "atom_vec_line.h" +#include "atom.h" +#include "domain.h" +#include "modify.h" +#include "force.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 +#define DELTA_BONUS 10000 +#define EPSILON 0.001 + +/* ---------------------------------------------------------------------- */ + +AtomVecLine::AtomVecLine(LAMMPS *lmp, int narg, char **arg) : + AtomVec(lmp, narg, arg) +{ + molecular = 0; + + comm_x_only = comm_f_only = 0; + size_forward = 4; + size_reverse = 6; + size_border = 10; + size_velocity = 6; + size_data_atom = 8; + size_data_vel = 7; + size_data_bonus = 5; + xcol_data = 6; + + atom->line_flag = 1; + atom->molecule_flag = atom->rmass_flag = 1; + atom->omega_flag = atom->torque_flag = 1; + + nlocal_bonus = nghost_bonus = nmax_bonus = 0; + bonus = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecLine::~AtomVecLine() +{ + memory->sfree(bonus); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::init() +{ + AtomVec::init(); + + if (domain->dimension != 2) + error->all(FLERR,"Atom_style line can only be used in 2d simulations"); +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecLine::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atom->nmax = nmax; + + tag = memory->grow(atom->tag,nmax,"atom:tag"); + type = memory->grow(atom->type,nmax,"atom:type"); + mask = memory->grow(atom->mask,nmax,"atom:mask"); + image = memory->grow(atom->image,nmax,"atom:image"); + x = memory->grow(atom->x,nmax,3,"atom:x"); + v = memory->grow(atom->v,nmax,3,"atom:v"); + f = memory->grow(atom->f,nmax,3,"atom:f"); + + molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); + rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); + omega = memory->grow(atom->omega,nmax,3,"atom:omega"); + torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + line = memory->grow(atom->line,nmax,"atom:line"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecLine::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + molecule = atom->molecule; rmass = atom->rmass; + omega = atom->omega; torque = atom->torque; +} + +/* ---------------------------------------------------------------------- + grow bonus data structure +------------------------------------------------------------------------- */ + +void AtomVecLine::grow_bonus() +{ + nmax_bonus += DELTA_BONUS; + if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), + "atom:bonus"); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecLine::copy(int i, int j, int delflag) +{ + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + molecule[j] = molecule[i]; + rmass[j] = rmass[i]; + omega[j][0] = omega[i][0]; + omega[j][1] = omega[i][1]; + omega[j][2] = omega[i][2]; + + // if delflag and atom J has bonus data, then delete it + + if (delflag && line[j] >= 0) { + copy_bonus(nlocal_bonus-1,line[j]); + nlocal_bonus--; + } + + // if atom I has bonus data and not deleting I, repoint I's bonus to J + + if (line[i] >= 0 && i != j) bonus[line[i]].ilocal = j; + line[j] = line[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j); +} + +/* ---------------------------------------------------------------------- + copy bonus data from I to J, effectively deleting the J entry + insure index pointers between per-atom and bonus data are updated +------------------------------------------------------------------------- */ + +void AtomVecLine::copy_bonus(int i, int j) +{ + memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); + line[bonus[j].ilocal] = j; +} + +/* ---------------------------------------------------------------------- + clear ghost info in bonus data + called before ghosts are recommunicated in comm and irregular +------------------------------------------------------------------------- */ + +void AtomVecLine::clear_bonus() +{ + nghost_bonus = 0; +} + +/* ---------------------------------------------------------------------- + set length value in bonus data for particle I + oriented along x axis + this may create or delete entry in bonus data +------------------------------------------------------------------------- */ + +void AtomVecLine::set_length(int i, double value) +{ + if (line[i] < 0) { + if (value == 0.0) return; + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = value; + bonus[nlocal_bonus].theta = 0.0; + bonus[nlocal_bonus].ilocal = i; + line[i] = nlocal_bonus++; + } else if (value == 0.0) { + copy_bonus(nlocal_bonus-1,line[i]); + nlocal_bonus--; + line[i] = -1; + } else bonus[line[i]].length = value; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + omega[i][0] = buf[m++]; + omega[i][1] = buf[m++]; + omega[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_reverse(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_reverse_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_reverse_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_border(int n, int first, double *buf) +{ + int i,j,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_border_vel(int n, int first, double *buf) +{ + int i,j,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + omega[i][0] = buf[m++]; + omega[i][1] = buf[m++]; + omega[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,j,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + } + return m; +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them +------------------------------------------------------------------------- */ + +int AtomVecLine::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = omega[i][0]; + buf[m++] = omega[i][1]; + buf[m++] = omega[i][2]; + + if (line[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = line[i]; + buf[m++] = bonus[j].length; + buf[m++] = bonus[j].theta; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + omega[nlocal][0] = buf[m++]; + omega[nlocal][1] = buf[m++]; + omega[nlocal][2] = buf[m++]; + + line[nlocal] = static_cast (buf[m++]); + if (line[nlocal] == 0) line[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = buf[m++]; + bonus[nlocal_bonus].theta = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + line[nlocal] = nlocal_bonus++; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecLine::size_restart() +{ + int i; + + int n = 0; + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (line[i] >= 0) n += 19; + else n += 17; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecLine::pack_restart(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = omega[i][0]; + buf[m++] = omega[i][1]; + buf[m++] = omega[i][2]; + + if (line[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = line[i]; + buf[m++] = bonus[j].length; + buf[m++] = bonus[j].theta; + } + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecLine::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + omega[nlocal][0] = buf[m++]; + omega[nlocal][1] = buf[m++]; + omega[nlocal][2] = buf[m++]; + + line[nlocal] = static_cast (buf[m++]); + if (line[nlocal] == 0) line[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = buf[m++]; + bonus[nlocal_bonus].theta = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + line[nlocal] = nlocal_bonus++; + } + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecLine::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = (512 << 20) | (512 << 10) | 512; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + molecule[nlocal] = 0; + rmass[nlocal] = 1.0; + omega[nlocal][0] = 0.0; + omega[nlocal][1] = 0.0; + omega[nlocal][2] = 0.0; + line[nlocal] = -1; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecLine::data_atom(double *coord, int imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = atoi(values[0]); + if (tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + + molecule[nlocal] = atoi(values[1]); + + type[nlocal] = atoi(values[2]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + line[nlocal] = atoi(values[3]); + if (line[nlocal] == 0) line[nlocal] = -1; + else if (line[nlocal] == 1) line[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[4]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + omega[nlocal][0] = 0.0; + omega[nlocal][1] = 0.0; + omega[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecLine::data_atom_hybrid(int nlocal, char **values) +{ + molecule[nlocal] = atoi(values[0]); + + line[nlocal] = atoi(values[1]); + if (line[nlocal] == 0) line[nlocal] = -1; + else if (line[nlocal] == 1) line[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[2]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + return 3; +} + +/* ---------------------------------------------------------------------- + unpack one line from Lines section of data file +------------------------------------------------------------------------- */ + +void AtomVecLine::data_atom_bonus(int m, char **values) +{ + if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom"); + + if (nlocal_bonus == nmax_bonus) grow_bonus(); + + double x1 = atof(values[0]); + double y1 = atof(values[1]); + double x2 = atof(values[2]); + double y2 = atof(values[3]); + double dx = x2 - x1; + double dy = y2 - y1; + double length = sqrt(dx*dx + dy*dy); + + bonus[nlocal_bonus].length = length; + if (dy >= 0.0) bonus[nlocal_bonus].theta = acos(dx/length); + else bonus[nlocal_bonus].theta = -acos(dx/length); + + double xc = 0.5*(x1+x2); + double yc = 0.5*(y1+y2); + dx = xc - x[m][0]; + dy = yc - x[m][1]; + double delta = sqrt(dx*dx + dy*dy); + + if (delta/length > EPSILON) + error->one(FLERR,"Inconsistent line segment in data file"); + + x[m][0] = xc; + x[m][1] = yc; + + // reset line mass + // previously stored density in rmass + + rmass[m] *= length; + + bonus[nlocal_bonus].ilocal = m; + line[m] = nlocal_bonus++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecLine::data_vel(int m, char **values) +{ + v[m][0] = atof(values[0]); + v[m][1] = atof(values[1]); + v[m][2] = atof(values[2]); + omega[m][0] = atof(values[3]); + omega[m][1] = atof(values[4]); + omega[m][2] = atof(values[5]); +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Velocities section of data file +------------------------------------------------------------------------- */ + +int AtomVecLine::data_vel_hybrid(int m, char **values) +{ + omega[m][0] = atof(values[0]); + omega[m][1] = atof(values[1]); + omega[m][2] = atof(values[2]); + return 3; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecLine::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3); + + if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); + if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); + if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("line")) bytes += memory->usage(line,nmax); + + bytes += nmax_bonus*sizeof(Bonus); + + return bytes; +} + +/* ---------------------------------------------------------------------- + check consistency of internal Bonus data structure + n = # of atoms in regular structure to check against +------------------------------------------------------------------------- */ + +/* +void AtomVecLine::consistency_check(int n, char *str) +{ + int iflag = 0; + int count = 0; + for (int i = 0; i < n; i++) { + + if (line[i] >= 0) { + count++; + if (line[i] >= nlocal_bonus) iflag++; + if (bonus[line[i]].ilocal != i) iflag++; + //if (comm->me == 1 && update->ntimestep == 873) + // printf("CCHK %s: %d %d: %d %d: %d %d\n", + // str,i,n,line[i],nlocal_bonus,bonus[line[i]].ilocal,iflag); + } + } + + if (iflag) { + char msg[128]; + sprintf(msg,"BAD VECLINE PTRS: %s: %d %d: %d\n",str,comm->me, + update->ntimestep,iflag); + error->one(FLERR,msg); + } + + if (count != nlocal_bonus) { + char msg[128]; + sprintf(msg,"BAD VECLINE COUNT: %s: %d %d: %d %d\n", + str,comm->me,update->ntimestep,count,nlocal_bonus); + error->one(FLERR,msg); + } +} +*/ diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h new file mode 100644 index 0000000000..3dd6d6e37c --- /dev/null +++ b/src/atom_vec_line.h @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(line,AtomVecLine) + +#else + +#ifndef LMP_ATOM_VEC_LINE_H +#define LMP_ATOM_VEC_LINE_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecLine : public AtomVec { + public: + struct Bonus { + double length,theta; + int ilocal; + }; + struct Bonus *bonus; + + AtomVecLine(class LAMMPS *, int, char **); + ~AtomVecLine(); + void init(); + void grow(int); + void grow_reset(); + void copy(int, int, int); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_reverse(int, int, double *); + int pack_reverse_hybrid(int, int, double *); + void unpack_reverse(int, int *, double *); + int unpack_reverse_hybrid(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, int, char **); + int data_atom_hybrid(int, char **); + void data_vel(int, char **); + int data_vel_hybrid(int, char **); + bigint memory_usage(); + + // manipulate Bonus data structure for extra atom info + + void clear_bonus(); + void data_atom_bonus(int, char **); + + // unique to AtomVecLine + + void set_length(int, double); + + private: + int *tag,*type,*mask,*image; + double **x,**v,**f; + int *molecule; + double *rmass; + double **omega,**torque; + int *line; + + int nlocal_bonus,nghost_bonus,nmax_bonus; + + void grow_bonus(); + void copy_bonus(int, int); + // void consistency_check(int, char *); +}; + +} + +#endif +#endif diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp new file mode 100644 index 0000000000..03aed7aa65 --- /dev/null +++ b/src/atom_vec_tri.cpp @@ -0,0 +1,1561 @@ +/* ---------------------------------------------------------------------- + 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 "lmptype.h" +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "atom_vec_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "domain.h" +#include "modify.h" +#include "force.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 +#define DELTA_BONUS 10000 +#define EPSILON 0.001 + +/* ---------------------------------------------------------------------- */ + +AtomVecTri::AtomVecTri(LAMMPS *lmp, int narg, char **arg) : + AtomVec(lmp, narg, arg) +{ + molecular = 0; + + comm_x_only = comm_f_only = 0; + size_forward = 7; + size_reverse = 6; + size_border = 24; + size_velocity = 6; + size_data_atom = 8; + size_data_vel = 7; + size_data_bonus = 10; + xcol_data = 6; + + atom->tri_flag = 1; + atom->molecule_flag = atom->rmass_flag = 1; + atom->angmom_flag = atom->torque_flag = 1; + + nlocal_bonus = nghost_bonus = nmax_bonus = 0; + bonus = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecTri::~AtomVecTri() +{ + memory->sfree(bonus); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::init() +{ + AtomVec::init(); + + if (domain->dimension != 3) + error->all(FLERR,"Atom_style tri can only be used in 3d simulations"); +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecTri::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atom->nmax = nmax; + + tag = memory->grow(atom->tag,nmax,"atom:tag"); + type = memory->grow(atom->type,nmax,"atom:type"); + mask = memory->grow(atom->mask,nmax,"atom:mask"); + image = memory->grow(atom->image,nmax,"atom:image"); + x = memory->grow(atom->x,nmax,3,"atom:x"); + v = memory->grow(atom->v,nmax,3,"atom:v"); + f = memory->grow(atom->f,nmax,3,"atom:f"); + + molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); + rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); + angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); + torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + tri = memory->grow(atom->tri,nmax,"atom:tri"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecTri::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + molecule = atom->molecule; rmass = atom->rmass; + angmom = atom->angmom; torque = atom->torque; +} + +/* ---------------------------------------------------------------------- + grow bonus data structure +------------------------------------------------------------------------- */ + +void AtomVecTri::grow_bonus() +{ + nmax_bonus += DELTA_BONUS; + if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), + "atom:bonus"); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J + if delflag and atom J has bonus data, then delete it +------------------------------------------------------------------------- */ + +void AtomVecTri::copy(int i, int j, int delflag) +{ + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + molecule[j] = molecule[i]; + rmass[j] = rmass[i]; + angmom[j][0] = angmom[i][0]; + angmom[j][1] = angmom[i][1]; + angmom[j][2] = angmom[i][2]; + + // if delflag and atom J has bonus data, then delete it + + if (delflag && tri[j] >= 0) { + copy_bonus(nlocal_bonus-1,tri[j]); + nlocal_bonus--; + } + + // if atom I has bonus data and not deleting I, repoint I's bonus to J + + if (tri[i] >= 0 && i != j) bonus[tri[i]].ilocal = j; + tri[j] = tri[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j); +} + +/* ---------------------------------------------------------------------- + copy bonus data from I to J, effectively deleting the J entry + insure index pointers between per-atom and bonus data are updated +------------------------------------------------------------------------- */ + +void AtomVecTri::copy_bonus(int i, int j) +{ + memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); + tri[bonus[j].ilocal] = j; +} + +/* ---------------------------------------------------------------------- + clear ghost info in bonus data + called before ghosts are recommunicated in comm and irregular +------------------------------------------------------------------------- */ + +void AtomVecTri::clear_bonus() +{ + nghost_bonus = 0; +} + +/* ---------------------------------------------------------------------- + set equilateral tri of size in bonus data for particle I + oriented symmetrically in xy plane + this may create or delete entry in bonus data +------------------------------------------------------------------------- */ + +void AtomVecTri::set_equilateral(int i, double size) +{ + if (tri[i] < 0) { + if (size == 0.0) return; + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = 1.0; + quat[1] = 0.0; + quat[2] = 0.0; + quat[3] = 0.0; + c1[0] = -size/2.0; + c1[1] = -sqrt(3.0)/2.0 * size / 3.0; + c1[2] = 0.0; + c2[0] = size/2.0; + c2[1] = -sqrt(3.0)/2.0 * size / 3.0; + c2[2] = 0.0; + c3[0] = 0.0; + c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; + c3[2] = 0.0; + inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; + bonus[nlocal_bonus].ilocal = i; + tri[i] = nlocal_bonus++; + } else if (size == 0.0) { + copy_bonus(nlocal_bonus-1,tri[i]); + nlocal_bonus--; + tri[i] = -1; + } else { + double *c1 = bonus[tri[i]].c1; + double *c2 = bonus[tri[i]].c2; + double *c3 = bonus[tri[i]].c3; + double *inertia = bonus[tri[i]].inertia; + c1[0] = -size/2.0; + c1[1] = -sqrt(3.0)/2.0 * size / 3.0; + c1[2] = 0.0; + c2[0] = size/2.0; + c2[1] = -sqrt(3.0)/2.0 * size / 3.0; + c2[2] = 0.0; + c3[0] = 0.0; + c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; + c3[2] = 0.0; + inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + double *quat; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_reverse(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_reverse_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_reverse_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_border(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_border_vel(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + } + return m; +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them +------------------------------------------------------------------------- */ + +int AtomVecTri::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (tri[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = tri[i]; + double *quat = bonus[j].quat; + double *c1 = bonus[j].c1; + double *c2 = bonus[j].c2; + double *c3 = bonus[j].c3; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + tri[nlocal] = static_cast (buf[m++]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + tri[nlocal] = nlocal_bonus++; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecTri::size_restart() +{ + int i; + + int n = 0; + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (tri[i] >= 0) n += 33; + else n += 17; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecTri::pack_restart(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (tri[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = tri[i]; + double *quat = bonus[j].quat; + double *c1 = bonus[j].c1; + double *c2 = bonus[j].c2; + double *c3 = bonus[j].c3; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecTri::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + tri[nlocal] = static_cast (buf[m++]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + tri[nlocal] = nlocal_bonus++; + } + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecTri::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = (512 << 20) | (512 << 10) | 512; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + molecule[nlocal] = 0; + rmass[nlocal] = 1.0; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + tri[nlocal] = -1; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecTri::data_atom(double *coord, int imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = atoi(values[0]); + if (tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + + molecule[nlocal] = atoi(values[1]); + + type[nlocal] = atoi(values[2]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + tri[nlocal] = atoi(values[3]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else if (tri[nlocal] == 1) tri[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[4]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one tri in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecTri::data_atom_hybrid(int nlocal, char **values) +{ + molecule[nlocal] = atoi(values[0]); + + tri[nlocal] = atoi(values[1]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else if (tri[nlocal] == 1) tri[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[2]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + return 3; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Tris section of data file +------------------------------------------------------------------------- */ + +void AtomVecTri::data_atom_bonus(int m, char **values) +{ + if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom"); + + if (nlocal_bonus == nmax_bonus) grow_bonus(); + + double c1[3],c2[3],c3[3]; + c1[0] = atof(values[0]); + c1[1] = atof(values[1]); + c1[2] = atof(values[2]); + c2[0] = atof(values[3]); + c2[1] = atof(values[4]); + c2[2] = atof(values[5]); + c3[0] = atof(values[6]); + c3[1] = atof(values[7]); + c3[2] = atof(values[8]); + + // check for duplicate points + + if (c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + if (c1[0] == c3[0] && c1[1] == c3[1] && c1[2] == c3[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + if (c2[0] == c3[0] && c2[1] == c3[1] && c2[2] == c3[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + + // size = length of one edge + + double c2mc1[2],c3mc1[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + double size = MAX(MathExtra::len3(c2mc1),MathExtra::len3(c3mc1)); + + // centroid = 1/3 of sum of vertices + + double centroid[3]; + centroid[0] = (c1[0]+c2[0]+c3[0]) / 3.0; + centroid[1] = (c1[1]+c2[1]+c3[1]) / 3.0; + centroid[2] = (c1[2]+c2[2]+c3[2]) / 3.0; + + double dx = centroid[0] - x[m][0]; + double dy = centroid[1] - x[m][1]; + double dz = centroid[2] - x[m][2]; + double delta = sqrt(dx*dx + dy*dy + dz*dz); + + if (delta/size > EPSILON) + error->one(FLERR,"Inconsistent triangle in data file"); + + x[m][0] = centroid[0]; + x[m][1] = centroid[1]; + x[m][2] = centroid[2]; + + // reset tri mass + // previously stored density in rmass + // tri area = 0.5 len(U x V), where U,V are edge vectors from one vertex + + double norm[3]; + MathExtra::cross3(c2mc1,c3mc1,norm); + double area = 0.5 * MathExtra::len3(norm); + rmass[m] *= area; + + // inertia = inertia tensor of triangle as 6-vector in Voigt notation + + double inertia[6]; + MathExtra::inertia_triangle(c1,c2,c3,rmass[m],inertia); + + // diagonalize inertia tensor via Jacobi rotations + // bonus[].inertia = 3 eigenvalues = principal moments of inertia + // evectors and exzy_space = 3 evectors = principal axes of triangle + + double tensor[3][3],evectors[3][3]; + tensor[0][0] = inertia[0]; + tensor[1][1] = inertia[1]; + tensor[2][2] = inertia[2]; + tensor[1][2] = tensor[2][1] = inertia[3]; + tensor[0][2] = tensor[2][0] = inertia[4]; + tensor[0][1] = tensor[1][0] = inertia[5]; + + int ierror = MathExtra::jacobi(tensor,bonus[nlocal_bonus].inertia,evectors); + if (ierror) error->one(FLERR,"Insufficient Jacobi rotations for triangle"); + + double ex_space[3],ey_space[3],ez_space[3]; + ex_space[0] = evectors[0][0]; + ex_space[1] = evectors[1][0]; + ex_space[2] = evectors[2][0]; + ey_space[0] = evectors[0][1]; + ey_space[1] = evectors[1][1]; + ey_space[2] = evectors[2][1]; + ez_space[0] = evectors[0][2]; + ez_space[1] = evectors[1][2]; + ez_space[2] = evectors[2][2]; + + // enforce 3 orthogonal vectors as a right-handed coordinate system + // flip 3rd vector if needed + + MathExtra::cross3(ex_space,ey_space,norm); + if (MathExtra::dot3(norm,ez_space) < 0.0) MathExtra::negate3(ez_space); + + // create initial quaternion + + MathExtra::exyz_to_q(ex_space,ey_space,ez_space,bonus[nlocal_bonus].quat); + + // bonus c1,c2,c3 = displacement of c1,c2,c3 from centroid + // in basis of principal axes + + double disp[3]; + MathExtra::sub3(c1,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c1); + MathExtra::sub3(c2,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c2); + MathExtra::sub3(c3,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c3); + + bonus[nlocal_bonus].ilocal = m; + tri[m] = nlocal_bonus++; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecTri::data_vel(int m, char **values) +{ + v[m][0] = atof(values[0]); + v[m][1] = atof(values[1]); + v[m][2] = atof(values[2]); + angmom[m][0] = atof(values[3]); + angmom[m][1] = atof(values[4]); + angmom[m][2] = atof(values[5]); +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one tri in Velocities section of data file +------------------------------------------------------------------------- */ + +int AtomVecTri::data_vel_hybrid(int m, char **values) +{ + angmom[m][0] = atof(values[0]); + angmom[m][1] = atof(values[1]); + angmom[m][2] = atof(values[2]); + return 3; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecTri::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3); + + if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); + if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); + if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("tri")) bytes += memory->usage(tri,nmax); + + bytes += nmax_bonus*sizeof(Bonus); + + return bytes; +} diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h new file mode 100644 index 0000000000..33f3e9cd6e --- /dev/null +++ b/src/atom_vec_tri.h @@ -0,0 +1,97 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(tri,AtomVecTri) + +#else + +#ifndef LMP_ATOM_VEC_TRI_H +#define LMP_ATOM_VEC_TRI_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecTri : public AtomVec { + public: + struct Bonus { + double quat[4]; + double c1[3],c2[3],c3[3]; + double inertia[3]; + int ilocal; + }; + struct Bonus *bonus; + + AtomVecTri(class LAMMPS *, int, char **); + ~AtomVecTri(); + void init(); + void grow(int); + void grow_reset(); + void copy(int, int, int); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_reverse(int, int, double *); + int pack_reverse_hybrid(int, int, double *); + void unpack_reverse(int, int *, double *); + int unpack_reverse_hybrid(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, int, char **); + int data_atom_hybrid(int, char **); + void data_vel(int, char **); + int data_vel_hybrid(int, char **); + bigint memory_usage(); + + // manipulate Bonus data structure for extra atom info + + void clear_bonus(); + void data_atom_bonus(int, char **); + + // unique to AtomVecTri + + void set_equilateral(int, double); + + private: + int *tag,*type,*mask,*image; + double **x,**v,**f; + int *molecule; + double *rmass; + double **angmom,**torque; + int *tri; + + int nlocal_bonus,nghost_bonus,nmax_bonus; + + void grow_bonus(); + void copy_bonus(int, int); +}; + +} + +#endif +#endif From 89a39c742569da723d22d37e581f7e045cfdf82c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:01:42 +0000 Subject: [PATCH 211/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7148 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/Install.sh | 8 + src/ASPHERE/pair_line.cpp | 444 ++++++++++++++++++++++++++ src/ASPHERE/pair_line.h | 61 ++++ src/ASPHERE/pair_tri.cpp | 637 ++++++++++++++++++++++++++++++++++++++ src/ASPHERE/pair_tri.h | 61 ++++ 5 files changed, 1211 insertions(+) create mode 100644 src/ASPHERE/pair_line.cpp create mode 100644 src/ASPHERE/pair_line.h create mode 100644 src/ASPHERE/pair_tri.cpp create mode 100644 src/ASPHERE/pair_tri.h diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index c896a5c285..2f6f974332 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -12,7 +12,9 @@ if (test $1 = 1) then cp fix_nve_tri.cpp .. cp fix_nvt_asphere.cpp .. cp pair_gayberne.cpp .. + cp pair_line.cpp .. cp pair_resquared.cpp .. + cp pair_tri.cpp .. cp compute_erotate_asphere.h .. cp compute_temp_asphere.h .. @@ -24,7 +26,9 @@ if (test $1 = 1) then cp fix_nve_tri.h .. cp fix_nvt_asphere.h .. cp pair_gayberne.h .. + cp pair_line.h .. cp pair_resquared.h .. + cp pair_tri.h .. elif (test $1 = 0) then @@ -38,7 +42,9 @@ elif (test $1 = 0) then rm -f ../fix_nve_tri.cpp rm -f ../fix_nvt_asphere.cpp rm -f ../pair_gayberne.cpp + rm -f ../pair_line.cpp rm -f ../pair_resquared.cpp + rm -f ../pair_tri.cpp rm -f ../compute_erotate_asphere.h rm -f ../compute_temp_asphere.h @@ -50,6 +56,8 @@ elif (test $1 = 0) then rm -f ../fix_nve_tri.h rm -f ../fix_nvt_asphere.h rm -f ../pair_gayberne.h + rm -f ../pair_line.h rm -f ../pair_resquared.h + rm -f ../pair_tri.h fi diff --git a/src/ASPHERE/pair_line.cpp b/src/ASPHERE/pair_line.cpp new file mode 100644 index 0000000000..4a3902c888 --- /dev/null +++ b/src/ASPHERE/pair_line.cpp @@ -0,0 +1,444 @@ +/* ---------------------------------------------------------------------- + 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_line.h" +#include "atom.h" +#include "atom_vec_line.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +PairLine::PairLine(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecLine *) atom->style_match("line"); + if (!avec) error->all(FLERR,"Pair line requires atom style line"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairLine::~PairLine() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLine::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + int *line = atom->line; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + 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]) continue; + + // line/line interactions = NxN particles + + evdwl = 0.0; + if (line[i] >= 0 && line[j] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + } + + // line/particle interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[i] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + } + } + + // particle/line interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[j] >= 0) { + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + + if (newton_pair || j < nlocal) { + f[j][0] += fj[0]; + f[j][1] += fj[1]; + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairLine::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairLine::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(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 PairLine::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairLine::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + discretize line segment I into N sub-segments no more than sigma in length + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairLine::discretize(int i, double sigma) +{ + AtomVecLine::Bonus *bonus = avec->bonus; + double length = bonus[atom->line[i]].length; + double theta = bonus[atom->line[i]].theta; + int n = static_cast (length/sigma) + 1; + dnum[i] = n; + dfirst[i] = ndiscrete; + + if (ndiscrete + n > dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + + double *x = atom->x[i]; + sigma = length/n; + double delta; + + for (int m = 0; m < n; m++) { + delta = -0.5 + (2*m+1)/(2.0*n); + discrete[ndiscrete].dx = delta*length*cos(theta); + discrete[ndiscrete].dy = delta*length*sin(theta); + discrete[ndiscrete].sigma = sigma; + ndiscrete++; + } +} diff --git a/src/ASPHERE/pair_line.h b/src/ASPHERE/pair_line.h new file mode 100644 index 0000000000..6598bfe6c1 --- /dev/null +++ b/src/ASPHERE/pair_line.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(line,PairLine) + +#else + +#ifndef LMP_PAIR_LINE_H +#define LMP_PAIR_LINE_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairLine : public Pair { + public: + PairLine(class LAMMPS *); + ~PairLine(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecLine *avec; + + struct Discrete { + double dx,dy; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double); +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/pair_tri.cpp b/src/ASPHERE/pair_tri.cpp new file mode 100644 index 0000000000..0a40b8fb06 --- /dev/null +++ b/src/ASPHERE/pair_tri.cpp @@ -0,0 +1,637 @@ +/* ---------------------------------------------------------------------- + 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_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_tri.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 20 + +/* ---------------------------------------------------------------------- */ + +PairTri::PairTri(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecTri *) atom->style_match("tri"); + if (!avec) error->all(FLERR,"Pair tri requires atom style tri"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairTri::~PairTri() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTri::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double dxi,dxj,dyi,dyj,dzi,dzj; + double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3]; + double dc1[3],dc2[3],dc3[3]; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + AtomVecTri::Bonus *bonus = avec->bonus; + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + int *tri = atom->tri; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + 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]) continue; + + // tri/tri interactions = NxN particles + // c1,c2,c3 = corner pts of triangle I or J + + evdwl = 0.0; + if (tri[i] >= 0 && tri[j] >= 0) { + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][0] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + } + + // tri/particle interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle I + + } else if (tri[i] >= 0) { + + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + xj[2] = x[j][2]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][2] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + } + } + + // particle/tri interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle J + + } else if (tri[j] >= 0) { + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairTri::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairTri::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(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 PairTri::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairTri::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 2 tris via bisecting longest side + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairTri::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double c1c2[3],c2c3[3],c1c3[3]; + + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 2 sub-triangles and recurse + + double c12[3],c23[3],c13[3],mid[3]; + + MathExtra::sub3(c2,c3,c23); + len1sq = MathExtra::lensq3(c23); + MathExtra::sub3(c1,c3,c13); + len2sq = MathExtra::lensq3(c13); + MathExtra::sub3(c1,c2,c12); + len3sq = MathExtra::lensq3(c12); + + double maxsq = MAX(len1sq,len2sq); + maxsq = MAX(maxsq,len3sq); + + if (len1sq == maxsq) { + MathExtra::add3(c2,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c1,c2,mid); + discretize(i,sigma,c1,c3,mid); + } else if (len2sq == maxsq) { + MathExtra::add3(c1,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c2,c1,mid); + discretize(i,sigma,c2,c3,mid); + } else { + MathExtra::add3(c1,c2,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c3,c1,mid); + discretize(i,sigma,c3,c2,mid); + } +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 6 tris via centroid + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +/* +void PairTri::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 6 sub-triangles and recurse + + double c1c2mid[3],c2c3mid[3],c1c3mid[3]; + + MathExtra::add3(c1,c2,c1c2mid); + MathExtra::scale3(0.5,c1c2mid); + MathExtra::add3(c2,c3,c2c3mid); + MathExtra::scale3(0.5,c2c3mid); + MathExtra::add3(c1,c3,c1c3mid); + MathExtra::scale3(0.5,c1c3mid); + + discretize(i,sigma,c1,c1c2mid,centroid); + discretize(i,sigma,c1,c1c3mid,centroid); + discretize(i,sigma,c2,c2c3mid,centroid); + discretize(i,sigma,c2,c1c2mid,centroid); + discretize(i,sigma,c3,c1c3mid,centroid); + discretize(i,sigma,c3,c2c3mid,centroid); +} + +*/ diff --git a/src/ASPHERE/pair_tri.h b/src/ASPHERE/pair_tri.h new file mode 100644 index 0000000000..fd1fe08bac --- /dev/null +++ b/src/ASPHERE/pair_tri.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tri,PairTri) + +#else + +#ifndef LMP_PAIR_TRI_H +#define LMP_PAIR_TRI_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairTri : public Pair { + public: + PairTri(class LAMMPS *); + ~PairTri(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecTri *avec; + + struct Discrete { + double dx,dy,dz; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double, double *, double *, double *); +}; + +} + +#endif +#endif From b0f09063e0ee5dfdc72dba28a877b4a1c1b442d4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:01:56 +0000 Subject: [PATCH 212/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7149 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/atom_style.html | 32 ++++++--- doc/atom_style.txt | 34 +++++---- doc/compute_erotate_asphere.html | 32 ++++++--- doc/compute_erotate_asphere.txt | 32 ++++++--- doc/compute_property_atom.html | 19 ++++- doc/compute_property_atom.txt | 20 ++++-- doc/fix.html | 3 + doc/fix.txt | 3 + doc/fix_rigid.html | 29 ++++---- doc/fix_rigid.txt | 29 ++++---- doc/fix_srd.html | 44 ++++++------ doc/fix_srd.txt | 44 ++++++------ doc/read_data.html | 99 +++++++++++++++++++++++--- doc/read_data.txt | 91 +++++++++++++++++++++--- doc/set.html | 115 ++++++++++++++++++++++-------- doc/set.txt | 118 ++++++++++++++++++++++--------- 16 files changed, 539 insertions(+), 205 deletions(-) diff --git a/doc/atom_style.html b/doc/atom_style.html index 8356e44dfc..8b16f36569 100644 --- a/doc/atom_style.html +++ b/doc/atom_style.html @@ -15,7 +15,7 @@

    atom_style style args 
     
    -
    • style = angle or atomic or bond or charge or dipole or electron or ellipsoid or full or meso or molecular or peri or sphere or hybrid +
      • style = angle or atomic or bond or charge or dipole or electron or ellipsoid or full or line or meso or molecular or peri or sphere or tri or hybrid
        args = none for any style except hybrid
         hybrid args = list of one or more sub-styles 
      @@ -61,10 +61,12 @@ quantities.
       electron  charge and spin and eradius  electronic force field 
       ellipsoid  shape, quaternion for particle orientation, angular momentum  extended aspherical particles 
       full  molecular + charge  bio-molecules 
      +line  end points, angular velocity  rigid bodies 
       meso  rho, e, cv  SPH particles 
       molecular  bonds, angles, dihedrals, impropers  uncharged molecules 
       peri  mass, volume  mesocopic Peridynamic models 
       sphere  diameter, mass, angular velocity  granular models 
      +tri  corner points, angular momentum  rigid bodies 
       wavepacket  charge, spin, eradius, etag, cs_re, cs_im  AWPMD 
       
       
      @@ -73,8 +75,8 @@ the mass command, except for the finite-size particle
       styles discussed below.  They assign mass on a per-atom basis.
       

      All of the styles define point particles, except the sphere, -ellipsoid, electron, peri, and wavepacket styles, which define -finite-size particles. +ellipsoid, electron, peri, wavepacket, line, and tri +styles, which define finite-size particles.

      For the sphere style, the particles are spheres and each stores a per-particle diameter and mass. If the diameter > 0.0, the particle @@ -104,6 +106,14 @@ cs= (cs_re,cs_im). Each of the wave packets is treated as a separate particle in LAMMPS, wave packets belonging to the same electron must have identical etag values.

      +

      For the line style, the particles are idealized line segments and +each stores a per-particle mass and length and orientation (i.e. the +end points of the line segment). +

      +

      For the tri style, the particles are planar triangles and each +stores a per-particle mass and size and orientation (i.e. the corner +points of the triangle). +


      Typically, simulations require only a single (non-hybrid) atom style. @@ -130,14 +140,14 @@ section.

      The angle, bond, full, and molecular styles are part of the MOLECULAR package. The dipole style is part of the "dipole" -package. The ellipsoid style is part of the "asphere" package. The -peri style is part of the PERI package for Peridynamics. The -electron style is part of the USER-EFF package for electronic force -fields. The meso style is part of the USER-SPH -package for smoothed particle hydrodyanmics (SPH). See this PDF -guide to using SPH in LAMMPS. The -wavepacket style is part of the USER-AWPMD package for the -antisymmetrized wave packet MD method. They are +package. The ellipsoid, line, and tri styles are part of the +"asphere" package. The peri style is part of the PERI package for +Peridynamics. The electron style is part of the USER-EFF package +for electronic force fields. The meso style is part +of the USER-SPH package for smoothed particle hydrodyanmics (SPH). +See this PDF guide to using SPH in +LAMMPS. The wavepacket style is part of the USER-AWPMD package for +the antisymmetrized wave packet MD method. They are only enabled if LAMMPS was built with that package. See the Making LAMMPS section for more info.

      diff --git a/doc/atom_style.txt b/doc/atom_style.txt index 8925291bc4..5f85786a7a 100644 --- a/doc/atom_style.txt +++ b/doc/atom_style.txt @@ -13,8 +13,8 @@ atom_style command :h3 atom_style style args :pre style = {angle} or {atomic} or {bond} or {charge} or {dipole} or \ - {electron} or {ellipsoid} or {full} or {meso} or {molecular} or \ - {peri} or {sphere} or {hybrid} :ul + {electron} or {ellipsoid} or {full} or {line} or {meso} or \ + {molecular} or {peri} or {sphere} or {tri} or {hybrid} :ul args = none for any style except {hybrid} {hybrid} args = list of one or more sub-styles :pre @@ -58,10 +58,12 @@ quantities. {electron} | charge and spin and eradius | electronic force field | {ellipsoid} | shape, quaternion for particle orientation, angular momentum | extended aspherical particles | {full} | molecular + charge | bio-molecules | +{line} | end points, angular velocity | rigid bodies | {meso} | rho, e, cv | SPH particles | {molecular} | bonds, angles, dihedrals, impropers | uncharged molecules | {peri} | mass, volume | mesocopic Peridynamic models | {sphere} | diameter, mass, angular velocity | granular models | +{tri} | corner points, angular momentum | rigid bodies | {wavepacket} | charge, spin, eradius, etag, cs_re, cs_im | AWPMD :tb(c=3,s=|) All of the styles assign mass to particles on a per-type basis, using @@ -69,8 +71,8 @@ the "mass"_mass.html command, except for the finite-size particle styles discussed below. They assign mass on a per-atom basis. All of the styles define point particles, except the {sphere}, -{ellipsoid}, {electron}, {peri}, and {wavepacket} styles, which define -finite-size particles. +{ellipsoid}, {electron}, {peri}, {wavepacket}, {line}, and {tri} +styles, which define finite-size particles. For the {sphere} style, the particles are spheres and each stores a per-particle diameter and mass. If the diameter > 0.0, the particle @@ -100,6 +102,14 @@ cs= (cs_re,cs_im). Each of the wave packets is treated as a separate particle in LAMMPS, wave packets belonging to the same electron must have identical {etag} values. +For the {line} style, the particles are idealized line segments and +each stores a per-particle mass and length and orientation (i.e. the +end points of the line segment). + +For the {tri} style, the particles are planar triangles and each +stores a per-particle mass and size and orientation (i.e. the corner +points of the triangle). + :line Typically, simulations require only a single (non-hybrid) atom style. @@ -126,14 +136,14 @@ This command cannot be used after the simulation box is defined by a The {angle}, {bond}, {full}, and {molecular} styles are part of the MOLECULAR package. The {dipole} style is part of the "dipole" -package. The {ellipsoid} style is part of the "asphere" package. The -{peri} style is part of the PERI package for Peridynamics. The -{electron} style is part of the USER-EFF package for "electronic force -fields"_pair_eff.html. The {meso} style is part of the USER-SPH -package for smoothed particle hydrodyanmics (SPH). See "this PDF -guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS. The -{wavepacket} style is part of the USER-AWPMD package for the -"antisymmetrized wave packet MD method"_pair_awpmd.html. They are +package. The {ellipsoid}, {line}, and {tri} styles are part of the +"asphere" package. The {peri} style is part of the PERI package for +Peridynamics. The {electron} style is part of the USER-EFF package +for "electronic force fields"_pair_eff.html. The {meso} style is part +of the USER-SPH package for smoothed particle hydrodyanmics (SPH). +See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in +LAMMPS. The {wavepacket} style is part of the USER-AWPMD package for +the "antisymmetrized wave packet MD method"_pair_awpmd.html. They are only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. diff --git a/doc/compute_erotate_asphere.html b/doc/compute_erotate_asphere.html index 642fb57767..161aef27c2 100644 --- a/doc/compute_erotate_asphere.html +++ b/doc/compute_erotate_asphere.html @@ -25,15 +25,19 @@

      Description:

      Define a computation that calculates the rotational kinetic energy of -a group of aspherical particles. +a group of aspherical particles. The aspherical particles can be +ellipsoids, or line segments, or triangles. See the +atom_style and read_data commands +for descriptions of these options.

      -

      The rotational kinetic energy is computed as 1/2 I w^2, where I is the -inertia tensor for the aspherical particle and w is its angular -velocity, which is computed from its angular momentum. +

      For all 3 types of particles, the rotational kinetic energy is +computed as 1/2 I w^2, where I is the inertia tensor for the +aspherical particle and w is its angular velocity, which is computed +from its angular momentum if needed.

      -

      IMPORTANT NOTE: For 2d models, particles are treated -as ellipsoids, not ellipses, meaning their moments of inertia will be -the same as in 3d. +

      IMPORTANT NOTE: For 2d models, ellipsoidal particles +are treated as ellipsoids, not ellipses, meaning their moments of +inertia will be the same as in 3d.

      Output info:

      @@ -47,9 +51,17 @@ scalar value will be in energy units.

      Restrictions:

      -

      This compute requires that atoms store a shape and quaternion -orientation and angular momentum as defined by the atom_style -ellipsoid command. +

      This compute requires that ellipsoidal particles atoms store a shape +and quaternion orientation and angular momentum as defined by the +atom_style ellipsoid command. +

      +

      This compute requires that line segment particles atoms store a length +and orientation and angular velocity as defined by the atom_style +line command. +

      +

      This compute requires that triangular particles atoms store a size and +shape and quaternion orientation and angular momentum as defined by +the atom_style tri command.

      All particles in the group must be finite-size. They cannot be point particles. diff --git a/doc/compute_erotate_asphere.txt b/doc/compute_erotate_asphere.txt index 607d9d4425..39aded0ed7 100644 --- a/doc/compute_erotate_asphere.txt +++ b/doc/compute_erotate_asphere.txt @@ -22,15 +22,19 @@ compute 1 all erotate/asphere :pre [Description:] Define a computation that calculates the rotational kinetic energy of -a group of aspherical particles. +a group of aspherical particles. The aspherical particles can be +ellipsoids, or line segments, or triangles. See the +"atom_style"_atom_style.html and "read_data"_read_data.html commands +for descriptions of these options. -The rotational kinetic energy is computed as 1/2 I w^2, where I is the -inertia tensor for the aspherical particle and w is its angular -velocity, which is computed from its angular momentum. +For all 3 types of particles, the rotational kinetic energy is +computed as 1/2 I w^2, where I is the inertia tensor for the +aspherical particle and w is its angular velocity, which is computed +from its angular momentum if needed. -IMPORTANT NOTE: For "2d models"_dimension.html, particles are treated -as ellipsoids, not ellipses, meaning their moments of inertia will be -the same as in 3d. +IMPORTANT NOTE: For "2d models"_dimension.html, ellipsoidal particles +are treated as ellipsoids, not ellipses, meaning their moments of +inertia will be the same as in 3d. [Output info:] @@ -44,9 +48,17 @@ scalar value will be in energy "units"_units.html. [Restrictions:] -This compute requires that atoms store a shape and quaternion -orientation and angular momentum as defined by the "atom_style -ellipsoid"_atom_style.html command. +This compute requires that ellipsoidal particles atoms store a shape +and quaternion orientation and angular momentum as defined by the +"atom_style ellipsoid"_atom_style.html command. + +This compute requires that line segment particles atoms store a length +and orientation and angular velocity as defined by the "atom_style +line"_atom_style.html command. + +This compute requires that triangular particles atoms store a size and +shape and quaternion orientation and angular momentum as defined by +the "atom_style tri"_atom_style.html command. All particles in the group must be finite-size. They cannot be point particles. diff --git a/doc/compute_property_atom.html b/doc/compute_property_atom.html index aec547b978..3adf2535dc 100644 --- a/doc/compute_property_atom.html +++ b/doc/compute_property_atom.html @@ -29,7 +29,11 @@ angmomx, angmomy, angmomz, shapex,shapey, shapez, quatw, quati, quatj, quatk, tqx, tqy, tqz, - spin, eradius, ervel, erforce + spin, eradius, ervel, erforce + end1x, end1y, end1z, end2x, end2y, end2z, + corner1x, corner1y, corner1z, + corner2x, corner2y, corner2z, + corner3x, corner3y, corner3z

            id = atom ID
             mol = molecule ID
      @@ -47,13 +51,15 @@
             radius,diameter = radius,diameter of spherical particle
             omegax,omegay,omegaz = angular velocity of extended particle
             angmomx,angmomy,angmomz = angular momentum of extended particle
      +      shapex,shapey,shapez = 3 diameters of aspherical particle
      +      quatw,quati,quatj,quatk = quaternion components for aspherical particles
             tqx,tqy,tqz = torque on extended particles
             spin = electron spin
             eradius = electron radius
             ervel = electron radial velocity
             erforce = electron radial force
      -      shapex,shapey,shapez = 3 diameters of aspherical particle
      -      quatw,quati,quatj,quatk = quaternion components for aspherical particles 
      +      end12x, end12y, end12z = end points of line segment
      +      coner123x, corner123y, corner123z = corner points of triangle 
       
    @@ -94,6 +100,13 @@ and quatk are also defined for ellipsoidal particles and store the See the set command for an explanation of the quaternion vector.

    +

    End1x, end1y, end1z, end2x, end2y, end2z, are defined for +line segment particles and define the end points of each line segment. +

    +

    Corner1x, corner1y, corner1z, corner2x, corner2y, +corner2z, corner3x, corner3y, corner3z, are defined for +triangular particles and define the corner points of each triangle. +

    Output info:

    This compute calculates a per-atom vector or per-atom array depending diff --git a/doc/compute_property_atom.txt b/doc/compute_property_atom.txt index f2a088be34..500ca25df4 100644 --- a/doc/compute_property_atom.txt +++ b/doc/compute_property_atom.txt @@ -23,8 +23,11 @@ input = one or more atom attributes :l angmomx, angmomy, angmomz, shapex,shapey, shapez, quatw, quati, quatj, quatk, tqx, tqy, tqz, - spin, eradius, ervel, erforce :pre - + spin, eradius, ervel, erforce + end1x, end1y, end1z, end2x, end2y, end2z, + corner1x, corner1y, corner1z, + corner2x, corner2y, corner2z, + corner3x, corner3y, corner3z :pre id = atom ID mol = molecule ID type = atom type @@ -41,13 +44,15 @@ input = one or more atom attributes :l radius,diameter = radius,diameter of spherical particle omegax,omegay,omegaz = angular velocity of extended particle angmomx,angmomy,angmomz = angular momentum of extended particle + shapex,shapey,shapez = 3 diameters of aspherical particle + quatw,quati,quatj,quatk = quaternion components for aspherical particles tqx,tqy,tqz = torque on extended particles spin = electron spin eradius = electron radius ervel = electron radial velocity erforce = electron radial force - shapex,shapey,shapez = 3 diameters of aspherical particle - quatw,quati,quatj,quatk = quaternion components for aspherical particles :pre + end12x, end12y, end12z = end points of line segment + coner123x, corner123y, corner123z = corner points of triangle :pre :ule [Examples:] @@ -87,6 +92,13 @@ and {quatk} are also defined for ellipsoidal particles and store the See the "set"_set.html command for an explanation of the quaternion vector. +{End1x}, {end1y}, {end1z}, {end2x}, {end2y}, {end2z}, are defined for +line segment particles and define the end points of each line segment. + +{Corner1x}, {corner1y}, {corner1z}, {corner2x}, {corner2y}, +{corner2z}, {corner3x}, {corner3y}, {corner3z}, are defined for +triangular particles and define the corner points of each triangle. + [Output info:] This compute calculates a per-atom vector or per-atom array depending diff --git a/doc/fix.html b/doc/fix.html index e73695d95e..c005536590 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -184,6 +184,7 @@ list of fix styles available in LAMMPS:

  • gcmc - grand canonical insertions/deletions
  • heat - add/subtract momentum-conserving heat
  • indent - impose force due to an indenter +
  • integrateU - Stokesian Dynamics evolution
  • langevin - Langevin temperature control
  • lineforce - constrain atoms to move in a line
  • momentum - zero the linear and/or angular momentum of a group of atoms @@ -200,8 +201,10 @@ list of fix styles available in LAMMPS:
  • nve - constant NVE time integration
  • nve/asphere - NVT for aspherical particles
  • nve/limit - NVE with limited step length +
  • nve/line - NVE for line segments
  • nve/noforce - NVE without forces (v only)
  • nve/sphere - NVT for spherical particles +
  • nve/tri - NVE for triangles
  • nvt - constant NVT time integration via Nose/Hoover
  • nvt/asphere - NVT for aspherical particles
  • nvt/sllod - NVT for NEMD with SLLOD equations diff --git a/doc/fix.txt b/doc/fix.txt index a31f5bf0b2..6f59881200 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -179,6 +179,7 @@ list of fix styles available in LAMMPS: "gcmc"_fix_gcmc.html - grand canonical insertions/deletions "heat"_fix_heat.html - add/subtract momentum-conserving heat "indent"_fix_indent.html - impose force due to an indenter +"integrateU"_fix_integrateU.html - Stokesian Dynamics evolution "langevin"_fix_langevin.html - Langevin temperature control "lineforce"_fix_lineforce.html - constrain atoms to move in a line "momentum"_fix_momentum.html - zero the linear and/or angular momentum of a group of atoms @@ -195,8 +196,10 @@ list of fix styles available in LAMMPS: "nve"_fix_nve.html - constant NVE time integration "nve/asphere"_fix_nve_asphere.html - NVT for aspherical particles "nve/limit"_fix_nve_limit.html - NVE with limited step length +"nve/line"_fix_nve_line.html - NVE for line segments "nve/noforce"_fix_nve_noforce.html - NVE without forces (v only) "nve/sphere"_fix_nve_sphere.html - NVT for spherical particles +"nve/tri"_fix_nve_tri.html - NVE for triangles "nvt"_fix_nh.html - constant NVT time integration via Nose/Hoover "nvt/asphere"_fix_nvt_asphere.html - NVT for aspherical particles "nvt/sllod"_fix_nvt_sllod.html - NVT for NEMD with SLLOD equations diff --git a/doc/fix_rigid.html b/doc/fix_rigid.html index 6d92361151..c15ed3ecfe 100644 --- a/doc/fix_rigid.html +++ b/doc/fix_rigid.html @@ -78,12 +78,13 @@ portions of a large biomolecule such as a protein.

    Example of small rigid bodies are patchy nanoparticles, such as those modeled in this paper by Sharon Glotzer's group, clumps of granular particles, lipid molecules consiting of one or more point -dipoles connected to other spheroids or ellipsoids, and coarse-grain -models of nano or colloidal particles consisting of a small number of -constituent particles. Note that the fix shake -command can also be used to rigidify small molecules of 2, 3, or 4 -atoms, e.g. water molecules. That fix treats the constituent atoms as -point masses. +dipoles connected to other spheroids or ellipsoids, irregular +particles built from line segments (2d) or triangles (3d), and +coarse-grain models of nano or colloidal particles consisting of a +small number of constituent particles. Note that the fix +shake command can also be used to rigidify small +molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats +the constituent atoms as point masses.

    These fixes also update the positions and velocities of the atoms in each rigid body via time integration. The rigid and rigid/nve @@ -118,14 +119,14 @@ setforce command), and integrating them as usual


    The constituent particles within a rigid body can be point particles -(the default in LAMMPS) or finite-size particles, such as spheres and -ellipsoids. See the atom_style sphere and ellipsoid -commands for more details on these kinds of particles. Finite-size -particles contribute differently to the moment of inertia of a rigid -body than do point particles. Finite-size particles can also -experience torque (e.g. due to frictional granular -interactions) and have an orientation. These -contributions are accounted for by these fixes. +(the default in LAMMPS) or finite-size particles, such as spheres or +ellipsoids or line segments or triangles. See the atom_style sphere +and ellipsoid and line and tri commands for more +details on these kinds of particles. Finite-size particles contribute +differently to the moment of inertia of a rigid body than do point +particles. Finite-size particles can also experience torque (e.g. due +to frictional granular interactions) and have an +orientation. These contributions are accounted for by these fixes.

    Forces between particles within a body do not contribute to the external force or torque on the body. Thus for computational diff --git a/doc/fix_rigid.txt b/doc/fix_rigid.txt index a6e50b2c07..3d49aedd6d 100644 --- a/doc/fix_rigid.txt +++ b/doc/fix_rigid.txt @@ -67,12 +67,13 @@ portions of a large biomolecule such as a protein. Example of small rigid bodies are patchy nanoparticles, such as those modeled in "this paper"_#Zhang by Sharon Glotzer's group, clumps of granular particles, lipid molecules consiting of one or more point -dipoles connected to other spheroids or ellipsoids, and coarse-grain -models of nano or colloidal particles consisting of a small number of -constituent particles. Note that the "fix shake"_fix_shake.html -command can also be used to rigidify small molecules of 2, 3, or 4 -atoms, e.g. water molecules. That fix treats the constituent atoms as -point masses. +dipoles connected to other spheroids or ellipsoids, irregular +particles built from line segments (2d) or triangles (3d), and +coarse-grain models of nano or colloidal particles consisting of a +small number of constituent particles. Note that the "fix +shake"_fix_shake.html command can also be used to rigidify small +molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats +the constituent atoms as point masses. These fixes also update the positions and velocities of the atoms in each rigid body via time integration. The {rigid} and {rigid/nve} @@ -107,14 +108,14 @@ setforce"_fix_setforce.html command), and integrating them as usual :line The constituent particles within a rigid body can be point particles -(the default in LAMMPS) or finite-size particles, such as spheres and -ellipsoids. See the "atom_style sphere and ellipsoid"_atom_style.html -commands for more details on these kinds of particles. Finite-size -particles contribute differently to the moment of inertia of a rigid -body than do point particles. Finite-size particles can also -experience torque (e.g. due to "frictional granular -interactions"_pair_gran.html) and have an orientation. These -contributions are accounted for by these fixes. +(the default in LAMMPS) or finite-size particles, such as spheres or +ellipsoids or line segments or triangles. See the "atom_style sphere +and ellipsoid and line and tri"_atom_style.html commands for more +details on these kinds of particles. Finite-size particles contribute +differently to the moment of inertia of a rigid body than do point +particles. Finite-size particles can also experience torque (e.g. due +to "frictional granular interactions"_pair_gran.html) and have an +orientation. These contributions are accounted for by these fixes. Forces between particles within a body do not contribute to the external force or torque on the body. Thus for computational diff --git a/doc/fix_srd.html b/doc/fix_srd.html index df029d06fd..8746be8e54 100644 --- a/doc/fix_srd.html +++ b/doc/fix_srd.html @@ -38,10 +38,7 @@ cubic values = style tolerance style = error or warn tolerance = fractional difference allowed (0 <= tol <= 1) - shift values = style seed - style = no or yes or possible - seed = random # seed (positive integer) - stream value = yes or no = whether or not streaming velocity is added for shear deformation + tstat value = yes or no = thermostat SRD particles or not

  • @@ -58,13 +55,14 @@ particles that serve as a background solvent when interacting with big in (Hecht). The key idea behind using SRD particles as a cheap coarse-grained solvent is that SRD particles do not interact with each other, but only with the solute particles, which in LAMMPS -can be spheroids, ellipsoids, or rigid bodies containing multiples -spherioids and ellipsoids. The collision and rotation properties of -the model imbue the SRD particles with fluid-like properties, -including an effective viscosity. Thus simulations with large solute -particles can be run more quickly, to measure solute propoerties like -diffusivity and viscosity in a background fluid. The usual LAMMPS -fixes for such simulations, such as fix deform, fix +can be spheroids, ellipsoids, or line segments, or triangles, or rigid +bodies containing multiple spherioids or ellipsoids or line segments +or triangles. The collision and rotation properties of the model +imbue the SRD particles with fluid-like properties, including an +effective viscosity. Thus simulations with large solute particles can +be run more quickly, to measure solute propoerties like diffusivity +and viscosity in a background fluid. The usual LAMMPS fixes for such +simulations, such as fix deform, fix viscosity, and fix nvt/sllod, can be used in conjunction with the SRD model.

    @@ -272,15 +270,19 @@ must still be specified.

    Note that shifting of SRD coordinates requires extra communication, hence it should not normally be enabled unless required.

    -

    The stream keyword should be used when SRD particles are used with -the fix deform command to perform a simulation -undergoing shear, e.g. to measure a viscosity. If the stream style -is set to yes, then the mean velocity of each bin of SRD particles -is set to the streaming velocity of the deforming box, each time SRD -velocities are reset, every N timesteps. If the stream style is set -to no, then the mean velocity is unchanged, which may mean that it -takes a long time for the SRD fluid to come to equilibrium with a -velocity profile that matches the simulation box deformation. +

    The tstat keyword will thermostat the SRD particles to the specified +Tsrd. This is done every N timesteps, during the velocity rotation +operation, by rescaling the thermal velocity of particles in each SRD +bin to the desired temperature. If there is a streaming velocity +associated with the system, e.g. due to use of the fix +deform command to perform a simulation undergoing +shear, then that is also accounted for. The mean velocity of each bin +of SRD particles is set to the position-dependent streaming velocity, +based on the coordinates of the center of the SRD bin. Note that for +streaming simulations, if no thermostatting is performed (the +default), then it may take a long time for the SRD fluid to come to +equilibrium with a velocity profile that matches the simulation box +deformation.


    @@ -358,7 +360,7 @@ for more info on packages.

    The option defaults are lamda inferred from Tsrd, collision = noslip, overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0, -search = hgrid, cubic = error 0.01, shift = no, stream = yes. +search = hgrid, cubic = error 0.01, shift = no, tstat = no.


    diff --git a/doc/fix_srd.txt b/doc/fix_srd.txt index a45c21392e..07dd49b861 100644 --- a/doc/fix_srd.txt +++ b/doc/fix_srd.txt @@ -33,10 +33,7 @@ keyword = {lamda} or {collision} or {overlap} or {inside} or {exact} or {radius} {cubic} values = style tolerance style = {error} or {warn} tolerance = fractional difference allowed (0 <= tol <= 1) - {shift} values = style seed - style = {no} or {yes} or {possible} - seed = random # seed (positive integer) - {stream} value = {yes} or {no} = whether or not streaming velocity is added for shear deformation :pre + {tstat} value = {yes} or {no} = thermostat SRD particles or not :pre :ule [Examples:] @@ -52,13 +49,14 @@ particles that serve as a background solvent when interacting with big in "(Hecht)"_#Hecht. The key idea behind using SRD particles as a cheap coarse-grained solvent is that SRD particles do not interact with each other, but only with the solute particles, which in LAMMPS -can be spheroids, ellipsoids, or rigid bodies containing multiples -spherioids and ellipsoids. The collision and rotation properties of -the model imbue the SRD particles with fluid-like properties, -including an effective viscosity. Thus simulations with large solute -particles can be run more quickly, to measure solute propoerties like -diffusivity and viscosity in a background fluid. The usual LAMMPS -fixes for such simulations, such as "fix deform"_fix_deform.html, "fix +can be spheroids, ellipsoids, or line segments, or triangles, or rigid +bodies containing multiple spherioids or ellipsoids or line segments +or triangles. The collision and rotation properties of the model +imbue the SRD particles with fluid-like properties, including an +effective viscosity. Thus simulations with large solute particles can +be run more quickly, to measure solute propoerties like diffusivity +and viscosity in a background fluid. The usual LAMMPS fixes for such +simulations, such as "fix deform"_fix_deform.html, "fix viscosity"_fix_viscosity.html, and "fix nvt/sllod"_fix_nvt_sllod.html, can be used in conjunction with the SRD model. @@ -266,15 +264,19 @@ must still be specified. Note that shifting of SRD coordinates requires extra communication, hence it should not normally be enabled unless required. -The {stream} keyword should be used when SRD particles are used with -the "fix deform"_fix_deform.html command to perform a simulation -undergoing shear, e.g. to measure a viscosity. If the {stream} style -is set to {yes}, then the mean velocity of each bin of SRD particles -is set to the streaming velocity of the deforming box, each time SRD -velocities are reset, every N timesteps. If the {stream} style is set -to {no}, then the mean velocity is unchanged, which may mean that it -takes a long time for the SRD fluid to come to equilibrium with a -velocity profile that matches the simulation box deformation. +The {tstat} keyword will thermostat the SRD particles to the specified +{Tsrd}. This is done every N timesteps, during the velocity rotation +operation, by rescaling the thermal velocity of particles in each SRD +bin to the desired temperature. If there is a streaming velocity +associated with the system, e.g. due to use of the "fix +deform"_fix_deform.html command to perform a simulation undergoing +shear, then that is also accounted for. The mean velocity of each bin +of SRD particles is set to the position-dependent streaming velocity, +based on the coordinates of the center of the SRD bin. Note that for +streaming simulations, if no thermostatting is performed (the +default), then it may take a long time for the SRD fluid to come to +equilibrium with a velocity profile that matches the simulation box +deformation. :line @@ -352,7 +354,7 @@ for more info on packages. The option defaults are lamda inferred from Tsrd, collision = noslip, overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0, -search = hgrid, cubic = error 0.01, shift = no, stream = yes. +search = hgrid, cubic = error 0.01, shift = no, tstat = no. :line diff --git a/doc/read_data.html b/doc/read_data.html index 2eced78fe0..fcf68f4680 100644 --- a/doc/read_data.html +++ b/doc/read_data.html @@ -80,6 +80,8 @@ is different than the default.
  • improper types = # of improper types in system
  • extra bond per atom = leave space for this many new bonds per atom
  • ellipsoids = # of ellipsoids in system +
  • lines = # of line segments in system +
  • triangles = # of triangles in system
  • xlo xhi = simulation box boundaries in x dimension
  • ylo yhi = simulation box boundaries in y dimension
  • zlo zhi = simulation box boundaries in z dimension @@ -156,16 +158,19 @@ added to the system when a simulation runs, e.g. by using the setting is only used with atom_style -ellipsoid and specifies how many of the atoms are -finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipsoidflag and the Ellipsoids section below. +

    The "ellipsoids" and "lines" and "triangles" settings are only used +with atom_style ellipsoid or line or tri and +specifies how many of the atoms are finite-size ellipsoids or lines or +triangles; the remainder are point particles. See the discussion of +ellipsoidflag and the Ellipsoids section below. See the discussion +of lineflag and the Lines section below. See the discussion of +triangleflag and the Triangles section below.


    These are the section keywords for the body of the file.

    -
    • Atoms, Velocities, Ellipsoids, Masses = atom-property sections +
      • Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles = atom-property sections
      • Bonds, Angles, Dihedrals, Impropers = molecular topology sections
      • Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, Improper Coeffs = force field sections
      • BondBond Coeffs, BondAngle Coeffs, MiddleBondTorsion Coeffs, EndBondTorsion Coeffs, AngleTorsion Coeffs, AngleAngleTorsion Coeffs, BondBond13 Coeffs, AngleAngle Coeffs = class 2 force field sections @@ -290,10 +295,12 @@ of analysis. electron atom-ID atom-type q spin eradius x y z ellipsoid atom-ID atom-type ellipsoidflag density x y z full atom-ID molecule-ID atom-type q x y z +line atom-ID molecule-ID atom-type lineflag density x y z meso atom-ID atom-type rho e cv x y z molecular atom-ID molecule-ID atom-type x y z peri atom-ID atom-type volume density x y z sphere atom-ID atom-type diameter density x y z +tri atom-ID molecule-ID atom-type triangleflag density x y z wavepacket atom-ID atom-type charge spin eradius etag cs_re cs_im x y z hybrid atom-ID atom-type x y z sub-style1 sub-style2 ... @@ -306,7 +313,9 @@ of analysis.
      • q = charge on atom (charge units)
      • diameter = diameter of spherical atom (distance units)
      • ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles -
      • density = density of atom (mass/distance^3 units) +
      • lineflag = 1 for line segment particles, 0 for point particles +
      • triangleflag = 1 for triangular particles, 0 for point particles +
      • density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
      • volume = volume of atom (distance^3 units)
      • x,y,z = coordinates of atom
      • mux,muy,muz = components of dipole moment of atom (dipole units) @@ -342,9 +351,13 @@ keep track of molecule assignments.

        The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle.

        -

        The ellipsoidflag determines whether the particle is a finite-size -ellipsoid of finite size, or a point particle. Additional attributes -must be defined for each ellipsoid in the Ellipsoids section. +

        The ellipsoidflag, lineflag, and triangleflag determine whether the +particle is a finite-size ellipsoid or line or triangle of finite +size, or a point particle. Additional attributes must be defined for +each ellipsoid in the Ellipsoids section. Additional attributes +must be defined for each line in the Lines section. Additional +attributes must be defined for each triangle in the Triangles +section.

        Some pair styles and fixes and computes that operate on finite-size particles allow for a mixture of finite-size and point particles. See @@ -352,8 +365,10 @@ the doc pages of individual commands for details.

        The density is used in conjunction with the particle volume for finite-size particles to set the mass of the particle as mass = -density * volume. If the volume is 0.0, meaning a point particle, -then the density value is used as the mass. +density * volume. In this context, volume can be a 3d quantity (for +spheres or ellipsoids), a 2d quantity (for triangles), or a 1d +quantity (for line segments). If the volume is 0.0, meaning a point +particle, then the density value is used as the mass.

        For atom_style hybrid, following the 5 initial values (ID,type,x,y,z), specific values for each sub-style must be listed. The order of the @@ -627,6 +642,37 @@ values in this section must be integers (1, not 1.0).


        +

        Lines section: +

        +
        • one line per line segment + +
        • line syntax: atom-ID x1 y1 x2 y2 + +
        • atom-ID = ID of atom which is a line segment + x1,y1 = 1st end point + x2,y2 = 2nd end point +example: + +
            12 1.0 0.0 2.0 0.0 
          +
          + +
        +

        The Lines section must appear if atom_style line +is used and any atoms are listed in the Atoms section with a +lineflag = 1. The number of lines should be specified in the header +section via the "lines" keyword. +

        +

        The 2 end points are the end points of the line segment. The ordering +of the 2 points should be such that using a right-hand rule to cross +the line segment with a unit vector in the +z direction, gives an +"outward" normal vector perpendicular to the line segment. +I.e. normal = (c2-c1) x (0,0,1). This orientation may be important +for defining some interactions. +

        +

        The Lines section must appear after the Atoms section. +

        +
        +

        Masses section:

        • one line per atom type @@ -685,6 +731,37 @@ script.


          +

          Triangles section: +

          +
          • one line per triangle + +
          • line syntax: atom-ID x1 y1 x2 y2 + +
          • atom-ID = ID of atom which is a line segment + x1,y1,z1 = 1st corner point + x2,y2,z2 = 2nd corner point + x3,y3,z3 = 3rd corner point +example: + +
              12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 
            +
            + +
          +

          The Triangles section must appear if atom_style +tri is used and any atoms are listed in the Atoms +section with a triangleflag = 1. The number of lines should be +specified in the header section via the "triangles" keyword. +

          +

          The 3 corner points are the corner points of the triangle. The +ordering of the 3 points should be such that using a right-hand rule +to go from point1 to point2 to point3 gives an "outward" normal vector +to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This +orientation may be important for defining some interactions. +

          +

          The Triangles section must appear after the Atoms section. +

          +
          +

          Velocities section:

          • one line per atom diff --git a/doc/read_data.txt b/doc/read_data.txt index d023d5de6e..b9fcccd0f6 100644 --- a/doc/read_data.txt +++ b/doc/read_data.txt @@ -77,6 +77,8 @@ is different than the default. {improper types} = # of improper types in system {extra bond per atom} = leave space for this many new bonds per atom {ellipsoids} = # of ellipsoids in system +{lines} = # of line segments in system +{triangles} = # of triangles in system {xlo xhi} = simulation box boundaries in x dimension {ylo yhi} = simulation box boundaries in y dimension {zlo zhi} = simulation box boundaries in z dimension @@ -153,16 +155,19 @@ added to the system when a simulation runs, e.g. by using the "fix bond/create"_fix_bond_create.html command. This will pre-allocate space in LAMMPS data structures for storing the new bonds. -The "ellipsoids" setting is only used with atom_style -ellipsoid"_atom_style.html and specifies how many of the atoms are -finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipsoidflag and the {Ellipsoids} section below. +The "ellipsoids" and "lines" and "triangles" settings are only used +with "atom_style ellipsoid or line or tri"_atom_style.html and +specifies how many of the atoms are finite-size ellipsoids or lines or +triangles; the remainder are point particles. See the discussion of +ellipsoidflag and the {Ellipsoids} section below. See the discussion +of lineflag and the {Lines} section below. See the discussion of +triangleflag and the {Triangles} section below. :line These are the section keywords for the body of the file. -{Atoms, Velocities, Ellipsoids, Masses} = atom-property sections +{Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles} = atom-property sections {Bonds, Angles, Dihedrals, Impropers} = molecular topology sections {Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, \ Improper Coeffs} = force field sections @@ -270,10 +275,12 @@ dipole: atom-ID atom-type q x y z mux muy muz electron: atom-ID atom-type q spin eradius x y z ellipsoid: atom-ID atom-type ellipsoidflag density x y z full: atom-ID molecule-ID atom-type q x y z +line: atom-ID molecule-ID atom-type lineflag density x y z meso: atom-ID atom-type rho e cv x y z molecular: atom-ID molecule-ID atom-type x y z peri: atom-ID atom-type volume density x y z sphere: atom-ID atom-type diameter density x y z +tri: atom-ID molecule-ID atom-type triangleflag density x y z wavepacket: atom-ID atom-type charge spin eradius etag cs_re cs_im x y z hybrid: atom-ID atom-type x y z sub-style1 sub-style2 ... :tb(s=:) @@ -285,7 +292,9 @@ atom-type = type of atom (1-Ntype) q = charge on atom (charge units) diameter = diameter of spherical atom (distance units) ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles -density = density of atom (mass/distance^3 units) +lineflag = 1 for line segment particles, 0 for point particles +triangleflag = 1 for triangular particles, 0 for point particles +density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) volume = volume of atom (distance^3 units) x,y,z = coordinates of atom mux,muy,muz = components of dipole moment of atom (dipole units) @@ -321,9 +330,13 @@ keep track of molecule assignments. The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle. -The ellipsoidflag determines whether the particle is a finite-size -ellipsoid of finite size, or a point particle. Additional attributes -must be defined for each ellipsoid in the {Ellipsoids} section. +The ellipsoidflag, lineflag, and triangleflag determine whether the +particle is a finite-size ellipsoid or line or triangle of finite +size, or a point particle. Additional attributes must be defined for +each ellipsoid in the {Ellipsoids} section. Additional attributes +must be defined for each line in the {Lines} section. Additional +attributes must be defined for each triangle in the {Triangles} +section. Some pair styles and fixes and computes that operate on finite-size particles allow for a mixture of finite-size and point particles. See @@ -331,8 +344,10 @@ the doc pages of individual commands for details. The density is used in conjunction with the particle volume for finite-size particles to set the mass of the particle as mass = -density * volume. If the volume is 0.0, meaning a point particle, -then the density value is used as the mass. +density * volume. In this context, volume can be a 3d quantity (for +spheres or ellipsoids), a 2d quantity (for triangles), or a 1d +quantity (for line segments). If the volume is 0.0, meaning a point +particle, then the density value is used as the mass. For atom_style hybrid, following the 5 initial values (ID,type,x,y,z), specific values for each sub-style must be listed. The order of the @@ -560,6 +575,33 @@ values in this section must be integers (1, not 1.0). :line +{Lines} section: + +one line per line segment :ulb,l +line syntax: atom-ID x1 y1 x2 y2 :l + atom-ID = ID of atom which is a line segment + x1,y1 = 1st end point + x2,y2 = 2nd end point +example: :l + 12 1.0 0.0 2.0 0.0 :pre +:ule + +The {Lines} section must appear if "atom_style line"_atom_style.html +is used and any atoms are listed in the {Atoms} section with a +lineflag = 1. The number of lines should be specified in the header +section via the "lines" keyword. + +The 2 end points are the end points of the line segment. The ordering +of the 2 points should be such that using a right-hand rule to cross +the line segment with a unit vector in the +z direction, gives an +"outward" normal vector perpendicular to the line segment. +I.e. normal = (c2-c1) x (0,0,1). This orientation may be important +for defining some interactions. + +The {Lines} section must appear after the {Atoms} section. + +:line + {Masses} section: one line per atom type :ulb,l @@ -605,6 +647,33 @@ script. :line +{Triangles} section: + +one line per triangle :ulb,l +line syntax: atom-ID x1 y1 x2 y2 :l + atom-ID = ID of atom which is a line segment + x1,y1,z1 = 1st corner point + x2,y2,z2 = 2nd corner point + x3,y3,z3 = 3rd corner point +example: :l + 12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 :pre +:ule + +The {Triangles} section must appear if "atom_style +tri"_atom_style.html is used and any atoms are listed in the {Atoms} +section with a triangleflag = 1. The number of lines should be +specified in the header section via the "triangles" keyword. + +The 3 corner points are the corner points of the triangle. The +ordering of the 3 points should be such that using a right-hand rule +to go from point1 to point2 to point3 gives an "outward" normal vector +to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This +orientation may be important for defining some interactions. + +The {Triangles} section must appear after the {Atoms} section. + +:line + {Velocities} section: one line per atom diff --git a/doc/set.html b/doc/set.html index a1feb65a31..06be9fb51c 100644 --- a/doc/set.html +++ b/doc/set.html @@ -21,7 +21,7 @@
          • one or more keyword/value pairs may be appended -
          • keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or mass or density or volume or image or +
          • keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or length or tri or theta or angmom or mass or density or volume or image or bond or angle or dihedral or improper or meso_e or meso_cv or meso_rho @@ -40,14 +40,22 @@ Dlen = magnitude of dipole moment (dipole units) quat values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule - theta = rotation angle in degrees + theta = rotation angle (degrees) quat/random value = seed seed = random # seed (positive integer) for quaternion orientations diameter value = diameter of spherical particle (distance units) shape value = Sx Sy Sz Sx,Sy,Sz = 3 diameters of ellipsoid (distance units) + length value = len + len = length of line segment (distance units) + tri value = side + side = side length of equilateral triangle (distance units) + theta value = angle (degrees) + angle = orientation of line segment with respect to x-axis + angmom values = Lx Ly Lz + Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units) mass value = per-atom mass (mass units) - density value = particle density for sphere or ellipsoid (mass/distance^3 units) + density value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) volume value = particle volume for Peridynamic particle (distance^3 units) image nx ny nz nx,ny,nz = which periodic image of the simulation box the atom is in @@ -143,26 +151,31 @@ the orientation of a particular atom is the same, regardless of how many processors are being used.

            Keyword quat uses the specified values to create a quaternion -(4-vector) that represents the orientation of the selected atoms. -Note that particles defined by atom_style ellipsoid -have 3 shape parameters. The 3 values must be non-zero for each -particle set by this command. They are used to specify the aspect -ratios of an ellipsoidal particle, which is oriented by default with -its x-axis along the simulation box's x-axis, and similarly for y and -z. If this body is rotated (via the right-hand rule) by an angle -theta around a unit rotation vector (a,b,c), then the quaternion that -represents its new orientation is given by (cos(theta/2), -a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c -values are the arguments to the quat keyword. LAMMPS normalizes the -quaternion in case (a,b,c) was not specified as a unit vector. For 2d -systems, the a,b,c values are ignored, since a rotation vector of -(0,0,1) is the only valid choice. +(4-vector) that represents the orientation of the selected atoms. The +particles must be ellipsoids as defined by the atom_style +ellipsoid command or triangles as defined by the +atom_style tri command. Note that particles defined +by atom_style ellipsoid have 3 shape parameters. +The 3 values must be non-zero for each particle set by this command. +They are used to specify the aspect ratios of an ellipsoidal particle, +which is oriented by default with its x-axis along the simulation +box's x-axis, and similarly for y and z. If this body is rotated (via +the right-hand rule) by an angle theta around a unit rotation vector +(a,b,c), then the quaternion that represents its new orientation is +given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2), +c*sin(theta/2)). The theta and a,b,c values are the arguments to the +quat keyword. LAMMPS normalizes the quaternion in case (a,b,c) was +not specified as a unit vector. For 2d systems, the a,b,c values are +ignored, since a rotation vector of (0,0,1) is the only valid choice.

            Keyword quat/random randomizes the orientation of the quaternion of -the selected atoms. Random numbers are used in such a way that the -orientation of a particular atom is the same, regardless of how many -processors are being used. For 2d systems, only orientations in the -xy plane are generated. As with keyword quat, the 3 shape values +the selected atoms. The particles must be ellipsoids as defined by +the atom_style ellipsoid command or triangles as +defined by the atom_style tri command. Random +numbers are used in such a way that the orientation of a particular +atom is the same, regardless of how many processors are being used. +For 2d systems, only orientations in the xy plane are generated. As +with keyword quat, for ellipsoidal particles, the 3 shape values must be non-zero for each particle set by this command.

            Keyword diameter sets the size of the selected atoms. The particles @@ -174,7 +187,7 @@ defined with a density, e.g. via the read_data command.

            Keyword shape sets the size and shape of the selected atoms. The -particles must be aspherical ellipsoids as defined by the atom_style +particles must be ellipsoids as defined by the atom_style ellipsoid command. The Sx, Sy, Sz settings are the 3 diameters of the ellipsoid in each direction. All 3 can be set to the same value, which means the ellipsoid is effectively a sphere. @@ -183,20 +196,60 @@ treated as a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the read_data command.

            +

            Keyword length sets the length of selected atoms. The particles +must be line segments as defined by the atom_style +line command. If the specified value is non-zero the +line segment is (re)set to a length = the specified value, centered +around the particle position, with an orientation along the x-axis. +If the specified value is 0.0, the particle will become a point +particle. Note that this command does not adjust the particle mass, +even if it was defined with a density, e.g. via the +read_data command. +

            +

            Keyword tri sets the size of selected atoms. The particles must be +triangles as defined by the atom_style tri command. +If the specified value is non-zero the triangle is (re)set to be an +equilateral triangle in the xy plane with side length = the specified +value, with a centroid at the particle position, with its base +parallel to the x axis, and the y-axis running from the center of the +base to the top point of the triangle. If the specified value is 0.0, +the particle will become a point particle. Note that this command +does not adjust the particle mass, even if it was defined with a +density, e.g. via the read_data command. +

            +

            Keyword theta sets the orientation of selected atoms. The particles +must be line segments as defined by the atom_style +line command. The specified value is used to set the +orientation angle of the line segments with respect to the x axis. +

            +

            Keyword angmom sets the angular momentum of selected atoms. The +particles must be ellipsoids as defined by the atom_style +ellipsoid command or triangles as defined by the +atom_style tri command. The angular momentum vector +of the particles is set to the 3 specified components. +

            Keyword mass sets the mass of all selected particles. The particles must have a per-atom mass attribute, as defined by the atom_style command. See the "mass" command for how to set mass values on a per-type basis.

            -

            Keyword density sets the mass of all selected particles. The -particles must have a per-atom mass attribute, as defined by the -atom_style command. See the "mass" command for how -to set mass values on a per-type basis. If the atom has a radius -attribute (see atom_style sphere) and its radius is -non-zero, its mass is set from the density and particle volume. The -same is true if the atom has a shape attribute (see atom_style -ellipsoid) and its 3 shape parameters are non-zero. -Otherwise the mass is set to the density value directly. +

            Keyword density also sets the mass of all selected particles, but in +a different way. The particles must have a per-atom mass attribute, +as defined by the atom_style command. If the atom +has a radius attribute (see atom_style sphere) and +its radius is non-zero, its mass is set from the density and particle +volume. If the atom has a shape attribute (see atom_style +ellipsoid) and its 3 shape parameters are non-zero, +then its mass is set from the density and particle volume. If the +atom has a length attribute (see atom_style line) +and its length is non-zero, then its mass is set from the density and +line segment length (the input density is assumed to be in +mass/distance units). If the atom has an area attribute (see +atom_style tri) and its area is non-zero, then its +mass is set from the density and triangle area (the input density is +assumed to be in mass/distance^2 units). If none of these cases are +valid, then the mass is set to the density value directly (the input +density is assumed to be in mass units).

            Keyword volume sets the volume of all selected particles. Currently, only the atom_style peri command defines diff --git a/doc/set.txt b/doc/set.txt index 8f37b29f1b..0c352d0958 100644 --- a/doc/set.txt +++ b/doc/set.txt @@ -17,8 +17,9 @@ ID = atom ID range or type range or mol ID range or group ID or region ID :l one or more keyword/value pairs may be appended :l keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ {charge} or {dipole} or {dipole/random} or {quat} or \ - {quat/random} or {diameter} or {shape} or {mass} or \ - {density} or {volume} or {image} or + {quat/random} or {diameter} or {shape} or \ + {length} or {tri} or {theta} or {angmom} or \ + {mass} or {density} or {volume} or {image} or {bond} or {angle} or {dihedral} or {improper} or {meso_e} or {meso_cv} or {meso_rho} :l {type} value = atom type @@ -36,14 +37,22 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ Dlen = magnitude of dipole moment (dipole units) {quat} values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule - theta = rotation angle in degrees + theta = rotation angle (degrees) {quat/random} value = seed seed = random # seed (positive integer) for quaternion orientations {diameter} value = diameter of spherical particle (distance units) {shape} value = Sx Sy Sz Sx,Sy,Sz = 3 diameters of ellipsoid (distance units) + {length} value = len + len = length of line segment (distance units) + {tri} value = side + side = side length of equilateral triangle (distance units) + {theta} value = angle (degrees) + angle = orientation of line segment with respect to x-axis + {angmom} values = Lx Ly Lz + Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units) {mass} value = per-atom mass (mass units) - {density} value = particle density for sphere or ellipsoid (mass/distance^3 units) + {density} value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) {volume} value = particle volume for Peridynamic particle (distance^3 units) {image} nx ny nz nx,ny,nz = which periodic image of the simulation box the atom is in @@ -138,26 +147,31 @@ the orientation of a particular atom is the same, regardless of how many processors are being used. Keyword {quat} uses the specified values to create a quaternion -(4-vector) that represents the orientation of the selected atoms. -Note that particles defined by "atom_style ellipsoid"_atom_style.html -have 3 shape parameters. The 3 values must be non-zero for each -particle set by this command. They are used to specify the aspect -ratios of an ellipsoidal particle, which is oriented by default with -its x-axis along the simulation box's x-axis, and similarly for y and -z. If this body is rotated (via the right-hand rule) by an angle -theta around a unit rotation vector (a,b,c), then the quaternion that -represents its new orientation is given by (cos(theta/2), -a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c -values are the arguments to the {quat} keyword. LAMMPS normalizes the -quaternion in case (a,b,c) was not specified as a unit vector. For 2d -systems, the a,b,c values are ignored, since a rotation vector of -(0,0,1) is the only valid choice. +(4-vector) that represents the orientation of the selected atoms. The +particles must be ellipsoids as defined by the "atom_style +ellipsoid"_atom_style.html command or triangles as defined by the +"atom_style tri"_atom_style.html command. Note that particles defined +by "atom_style ellipsoid"_atom_style.html have 3 shape parameters. +The 3 values must be non-zero for each particle set by this command. +They are used to specify the aspect ratios of an ellipsoidal particle, +which is oriented by default with its x-axis along the simulation +box's x-axis, and similarly for y and z. If this body is rotated (via +the right-hand rule) by an angle theta around a unit rotation vector +(a,b,c), then the quaternion that represents its new orientation is +given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2), +c*sin(theta/2)). The theta and a,b,c values are the arguments to the +{quat} keyword. LAMMPS normalizes the quaternion in case (a,b,c) was +not specified as a unit vector. For 2d systems, the a,b,c values are +ignored, since a rotation vector of (0,0,1) is the only valid choice. Keyword {quat/random} randomizes the orientation of the quaternion of -the selected atoms. Random numbers are used in such a way that the -orientation of a particular atom is the same, regardless of how many -processors are being used. For 2d systems, only orientations in the -xy plane are generated. As with keyword {quat}, the 3 shape values +the selected atoms. The particles must be ellipsoids as defined by +the "atom_style ellipsoid"_atom_style.html command or triangles as +defined by the "atom_style tri"_atom_style.html command. Random +numbers are used in such a way that the orientation of a particular +atom is the same, regardless of how many processors are being used. +For 2d systems, only orientations in the xy plane are generated. As +with keyword {quat}, for ellipsoidal particles, the 3 shape values must be non-zero for each particle set by this command. Keyword {diameter} sets the size of the selected atoms. The particles @@ -169,7 +183,7 @@ defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {shape} sets the size and shape of the selected atoms. The -particles must be aspherical ellipsoids as defined by the "atom_style +particles must be ellipsoids as defined by the "atom_style ellipsoid"_atom_style.html command. The {Sx}, {Sy}, {Sz} settings are the 3 diameters of the ellipsoid in each direction. All 3 can be set to the same value, which means the ellipsoid is effectively a sphere. @@ -178,20 +192,60 @@ treated as a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. +Keyword {length} sets the length of selected atoms. The particles +must be line segments as defined by the "atom_style +line"_atom_style.html command. If the specified value is non-zero the +line segment is (re)set to a length = the specified value, centered +around the particle position, with an orientation along the x-axis. +If the specified value is 0.0, the particle will become a point +particle. Note that this command does not adjust the particle mass, +even if it was defined with a density, e.g. via the +"read_data"_read_data.html command. + +Keyword {tri} sets the size of selected atoms. The particles must be +triangles as defined by the "atom_style tri"_atom_style.html command. +If the specified value is non-zero the triangle is (re)set to be an +equilateral triangle in the xy plane with side length = the specified +value, with a centroid at the particle position, with its base +parallel to the x axis, and the y-axis running from the center of the +base to the top point of the triangle. If the specified value is 0.0, +the particle will become a point particle. Note that this command +does not adjust the particle mass, even if it was defined with a +density, e.g. via the "read_data"_read_data.html command. + +Keyword {theta} sets the orientation of selected atoms. The particles +must be line segments as defined by the "atom_style +line"_atom_style.html command. The specified value is used to set the +orientation angle of the line segments with respect to the x axis. + +Keyword {angmom} sets the angular momentum of selected atoms. The +particles must be ellipsoids as defined by the "atom_style +ellipsoid"_atom_style.html command or triangles as defined by the +"atom_style tri"_atom_style.html command. The angular momentum vector +of the particles is set to the 3 specified components. + Keyword {mass} sets the mass of all selected particles. The particles must have a per-atom mass attribute, as defined by the "atom_style"_atom_style.html command. See the "mass" command for how to set mass values on a per-type basis. -Keyword {density} sets the mass of all selected particles. The -particles must have a per-atom mass attribute, as defined by the -"atom_style"_atom_style.html command. See the "mass" command for how -to set mass values on a per-type basis. If the atom has a radius -attribute (see "atom_style sphere"_atom_style.html) and its radius is -non-zero, its mass is set from the density and particle volume. The -same is true if the atom has a shape attribute (see "atom_style -ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero. -Otherwise the mass is set to the density value directly. +Keyword {density} also sets the mass of all selected particles, but in +a different way. The particles must have a per-atom mass attribute, +as defined by the "atom_style"_atom_style.html command. If the atom +has a radius attribute (see "atom_style sphere"_atom_style.html) and +its radius is non-zero, its mass is set from the density and particle +volume. If the atom has a shape attribute (see "atom_style +ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero, +then its mass is set from the density and particle volume. If the +atom has a length attribute (see "atom_style line"_atom_style.html) +and its length is non-zero, then its mass is set from the density and +line segment length (the input density is assumed to be in +mass/distance units). If the atom has an area attribute (see +"atom_style tri"_atom_style.html) and its area is non-zero, then its +mass is set from the density and triangle area (the input density is +assumed to be in mass/distance^2 units). If none of these cases are +valid, then the mass is set to the density value directly (the input +density is assumed to be in mass units). Keyword {volume} sets the volume of all selected particles. Currently, only the "atom_style peri"_atom_style.html command defines From 35aaafdfa7503889291ef6299bcaaf5021c7a8e0 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:02:14 +0000 Subject: [PATCH 213/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7150 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_nve_line.html | 60 +++++++++++++++++++++ doc/fix_nve_line.txt | 55 +++++++++++++++++++ doc/fix_nve_tri.html | 60 +++++++++++++++++++++ doc/fix_nve_tri.txt | 55 +++++++++++++++++++ doc/pair_line.html | 117 ++++++++++++++++++++++++++++++++++++++++ doc/pair_line.txt | 112 +++++++++++++++++++++++++++++++++++++++ doc/pair_tri.html | 120 ++++++++++++++++++++++++++++++++++++++++++ doc/pair_tri.txt | 115 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 694 insertions(+) create mode 100644 doc/fix_nve_line.html create mode 100755 doc/fix_nve_line.txt create mode 100644 doc/fix_nve_tri.html create mode 100755 doc/fix_nve_tri.txt create mode 100644 doc/pair_line.html create mode 100644 doc/pair_line.txt create mode 100644 doc/pair_tri.html create mode 100644 doc/pair_tri.txt diff --git a/doc/fix_nve_line.html b/doc/fix_nve_line.html new file mode 100644 index 0000000000..2a39e7b177 --- /dev/null +++ b/doc/fix_nve_line.html @@ -0,0 +1,60 @@ + +

            LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
            + + + + + + +
            + +

            fix nve/line command +

            +

            Syntax: +

            +
            fix ID group-ID nve/line 
            +
            +
            • ID, group-ID are documented in fix command +
            • nve/line = style name of this fix command +
            +

            Examples: +

            +
            fix 1 all nve/line 
            +
            +

            Description: +

            +

            Perform constant NVE integration to update position, velocity, +orientation, and angular velocity for line segment particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. +

            +

            This fix differs from the fix nve command, which +assumes point particles and only updates their position and velocity. +

            +

            Restart, fix_modify, output, run start/stop, minimize info: +

            +

            No information about this fix is written to binary restart +files. None of the fix_modify options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various output +commands. No parameter of this fix can +be used with the start/stop keywords of the run command. +This fix is not invoked during energy minimization. +

            +

            Restrictions: +

            +

            This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

            +

            This fix requires that particles be line segments as defined by the +atom_style line command. +

            +

            Related commands: +

            +

            fix nve, fix nve/asphere +

            +

            Default: none +

            + diff --git a/doc/fix_nve_line.txt b/doc/fix_nve_line.txt new file mode 100755 index 0000000000..da93f30dbb --- /dev/null +++ b/doc/fix_nve_line.txt @@ -0,0 +1,55 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix nve/line command :h3 + +[Syntax:] + +fix ID group-ID nve/line :pre + +ID, group-ID are documented in "fix"_fix.html command +nve/line = style name of this fix command :ul + +[Examples:] + +fix 1 all nve/line :pre + +[Description:] + +Perform constant NVE integration to update position, velocity, +orientation, and angular velocity for line segment particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. + +This fix differs from the "fix nve"_fix_nve.html command, which +assumes point particles and only updates their position and velocity. + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. None of the "fix_modify"_fix_modify.html options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various "output +commands"_Section_howto.html#howto_15. No parameter of this fix can +be used with the {start/stop} keywords of the "run"_run.html command. +This fix is not invoked during "energy minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +This fix requires that particles be line segments as defined by the +"atom_style line"_atom_style.html command. + +[Related commands:] + +"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html + +[Default:] none diff --git a/doc/fix_nve_tri.html b/doc/fix_nve_tri.html new file mode 100644 index 0000000000..cddb90aba3 --- /dev/null +++ b/doc/fix_nve_tri.html @@ -0,0 +1,60 @@ + +
            LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
            + + + + + + +
            + +

            fix nve/tri command +

            +

            Syntax: +

            +
            fix ID group-ID nve/tri 
            +
            +
            • ID, group-ID are documented in fix command +
            • nve/tri = style name of this fix command +
            +

            Examples: +

            +
            fix 1 all nve/tri 
            +
            +

            Description: +

            +

            Perform constant NVE integration to update position, velocity, +orientation, and angular momentum for triangular particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. +

            +

            This fix differs from the fix nve command, which +assumes point particles and only updates their position and velocity. +

            +

            Restart, fix_modify, output, run start/stop, minimize info: +

            +

            No information about this fix is written to binary restart +files. None of the fix_modify options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various output +commands. No parameter of this fix can +be used with the start/stop keywords of the run command. +This fix is not invoked during energy minimization. +

            +

            Restrictions: +

            +

            This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

            +

            This fix requires that particles be triangles as defined by the +atom_style tri command. +

            +

            Related commands: +

            +

            fix nve, fix nve/asphere +

            +

            Default: none +

            + diff --git a/doc/fix_nve_tri.txt b/doc/fix_nve_tri.txt new file mode 100755 index 0000000000..6ea568b4ea --- /dev/null +++ b/doc/fix_nve_tri.txt @@ -0,0 +1,55 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix nve/tri command :h3 + +[Syntax:] + +fix ID group-ID nve/tri :pre + +ID, group-ID are documented in "fix"_fix.html command +nve/tri = style name of this fix command :ul + +[Examples:] + +fix 1 all nve/tri :pre + +[Description:] + +Perform constant NVE integration to update position, velocity, +orientation, and angular momentum for triangular particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. + +This fix differs from the "fix nve"_fix_nve.html command, which +assumes point particles and only updates their position and velocity. + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. None of the "fix_modify"_fix_modify.html options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various "output +commands"_Section_howto.html#howto_15. No parameter of this fix can +be used with the {start/stop} keywords of the "run"_run.html command. +This fix is not invoked during "energy minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +This fix requires that particles be triangles as defined by the +"atom_style tri"_atom_style.html command. + +[Related commands:] + +"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html + +[Default:] none diff --git a/doc/pair_line.html b/doc/pair_line.html new file mode 100644 index 0000000000..205c5f3f91 --- /dev/null +++ b/doc/pair_line.html @@ -0,0 +1,117 @@ + +
            LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
            + + + + + + +
            + +

            pair_style line command +

            +

            Syntax: +

            +
            pair_style line cutoff 
            +
            +

            cutoff = global cutoff for interactions (distance units) +

            +

            Examples: +

            +
            pair_style line 3.0
            +pair_coeff * * 1.0 1.0
            +pair_coeff 1 1 1.0 1.5 2.5 
            +
            +

            Description: +

            +

            Style line treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the pair_style +lj/cut doc page for the definition of Lennard-Jones +interactions. +

            +

            The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. +

            +

            The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. +

            +

            The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. +

            +

            For style line, the following coefficients must be defined for each +pair of atoms types via the pair_coeff command as in +the examples above, or in the data file or restart files read by the +read_data or read_restart +commands: +

            +
            • epsilon (energy units) +
            • sigma (distance units) +
            • cutoff (distance units) +
            +

            The last coefficient is optional. If not specified, the global cutoff +is used. +

            +
            + +

            Mixing, shift, table, tail correction, restart, rRESPA info: +

            +

            For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

            +

            This pair style does not support the pair_modify +shift, table, and tail options. +

            +

            This pair style does not write its information to binary restart +files. +

            +

            This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

            +
            + +

            Restrictions: +

            +

            This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

            +

            Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +atom_style line command. +

            +

            Related commands: +

            +

            pair_coeff +

            +

            Default: none +

            + diff --git a/doc/pair_line.txt b/doc/pair_line.txt new file mode 100644 index 0000000000..160800250b --- /dev/null +++ b/doc/pair_line.txt @@ -0,0 +1,112 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style line command :h3 + +[Syntax:] + +pair_style line cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style line 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {line} treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the "pair_style +lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones +interactions. + +The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. + +The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. + +The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. + +For style {line}, the following coefficients must be defined for each +pair of atoms types via the "pair_coeff"_pair_coeff.html command as in +the examples above, or in the data file or restart files read by the +"read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +"atom_style line"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none diff --git a/doc/pair_tri.html b/doc/pair_tri.html new file mode 100644 index 0000000000..931819e107 --- /dev/null +++ b/doc/pair_tri.html @@ -0,0 +1,120 @@ + +
            LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
            + + + + + + +
            + +

            pair_style tri command +

            +

            Syntax: +

            +
            pair_style tri cutoff 
            +
            +

            cutoff = global cutoff for interactions (distance units) +

            +

            Examples: +

            +
            pair_style tri 3.0
            +pair_coeff * * 1.0 1.0
            +pair_coeff 1 1 1.0 1.5 2.5 
            +
            +

            Description: +

            +

            Style tri treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the pair_style lj/cut +doc page for the definition of Lennard-Jones interactions. +

            +

            The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. +

            +

            The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. +

            +

            The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. +

            +

            For style tri, the following coefficients must be defined for each +pair of atoms types via the pair_coeff command as in +the examples above, or in the data file or restart files read by the +read_data or read_restart +commands: +

            +
            • epsilon (energy units) +
            • sigma (distance units) +
            • cutoff (distance units) +
            +

            The last coefficient is optional. If not specified, the global cutoff +is used. +

            +
            + +

            Mixing, shift, table, tail correction, restart, rRESPA info: +

            +

            For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

            +

            This pair style does not support the pair_modify +shift, table, and tail options. +

            +

            This pair style does not write its information to binary restart +files. +

            +

            This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

            +
            + +

            Restrictions: +

            +

            This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

            +

            Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the atom_style +tri command. +

            +

            Related commands: +

            +

            pair_coeff +

            +

            Default: none +

            + diff --git a/doc/pair_tri.txt b/doc/pair_tri.txt new file mode 100644 index 0000000000..47aea453e5 --- /dev/null +++ b/doc/pair_tri.txt @@ -0,0 +1,115 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style tri command :h3 + +[Syntax:] + +pair_style tri cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style tri 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {tri} treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html +doc page for the definition of Lennard-Jones interactions. + +The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. + +The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. + +The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. + +For style {tri}, the following coefficients must be defined for each +pair of atoms types via the "pair_coeff"_pair_coeff.html command as in +the examples above, or in the data file or restart files read by the +"read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the "atom_style +tri"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none From 29ce252d9ab37e7fb2decea62b3871fef2f2bc1e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:06:55 +0000 Subject: [PATCH 214/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7151 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 30 +++++++++++++++--------------- doc/Section_commands.txt | 4 ++++ doc/fix.html | 1 - doc/fix.txt | 1 - doc/pair_coeff.html | 2 ++ doc/pair_coeff.txt | 2 ++ doc/pair_style.html | 2 ++ doc/pair_style.txt | 2 ++ 8 files changed, 27 insertions(+), 17 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 839ca37981..1781bf3b32 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -341,12 +341,12 @@ of each style or click on the style itself for a full description: efieldenforce2devaporateexternalfreezegcmcgravityheat indentlangevinlineforcemomentummovemsstnebnph nphugnph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/asphere -nve/limitnve/noforcenve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fcc -planeforcepoemspourpress/berendsenprintqeq/combreax/bondsrecenter -restrainrigidrigid/nverigid/nvtsetforceshakespringspring/rg -spring/selfsrdstore/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmd -ttmviscosityviscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93 -wall/reflectwall/regionwall/srd +nve/limitnve/linenve/noforcenve/spherenve/trinvtnvt/aspherenvt/sllod +nvt/sphereorient/fccplaneforcepoemspourpress/berendsenprintqeq/comb +reax/bondsrecenterrestrainrigidrigid/nverigid/nvtsetforceshake +springspring/rgspring/selfsrdstore/forcestore/statetemp/berendsentemp/rescale +thermal/conductivitytmdttmviscosityviscouswall/colloidwall/granwall/harmonic +wall/lj126wall/lj93wall/reflectwall/regionwall/srd

            These are fix styles contributed by users, which can be used if @@ -419,15 +419,15 @@ potentials. Click on the style itself for a full description: dpddpd/tstatdsmceam eam/alloyeam/fseimgauss gaybernegran/hertz/historygran/hookegran/hooke/history -hbond/dreiding/ljhbond/dreiding/morselj/charmm/coul/charmmlj/charmm/coul/charmm/implicit -lj/charmm/coul/longlj/class2lj/class2/coul/cutlj/class2/coul/long -lj/cutlj/cut/coul/cutlj/cut/coul/debyelj/cut/coul/long -lj/cut/coul/long/tip4plj/expandlj/gromacslj/gromacs/coul/gromacs -lj/smoothlj96/cutlubricatemeam -morseperi/lpsperi/pmbreax -reboresquaredsoftsw -tabletersofftersoff/zblyukawa -yukawa/colloid +hbond/dreiding/ljhbond/dreiding/morseline/ljlj/charmm/coul/charmm +lj/charmm/coul/charmm/implicitlj/charmm/coul/longlj/class2lj/class2/coul/cut +lj/class2/coul/longlj/cutlj/cut/coul/cutlj/cut/coul/debye +lj/cut/coul/longlj/cut/coul/long/tip4plj/expandlj/gromacs +lj/gromacs/coul/gromacslj/smoothlj96/cutlubricate +meammorseperi/lpsperi/pmb +reaxreboresquaredsoft +swtabletersofftersoff/zbl +tri/ljyukawayukawa/colloid

            These are pair styles contributed by users, which can be used if diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index d6e2e5dd17..67700fd323 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -438,8 +438,10 @@ of each style or click on the style itself for a full description: "nve"_fix_nve.html, "nve/asphere"_fix_nve_asphere.html, "nve/limit"_fix_nve_limit.html, +"nve/line"_fix_nve_line.html, "nve/noforce"_fix_nve_noforce.html, "nve/sphere"_fix_nve_sphere.html, +"nve/tri"_fix_nve_tri.html, "nvt"_fix_nh.html, "nvt/asphere"_fix_nvt_asphere.html, "nvt/sllod"_fix_nvt_sllod.html, @@ -638,6 +640,7 @@ potentials. Click on the style itself for a full description: "gran/hooke/history"_pair_gran.html, "hbond/dreiding/lj"_pair_hbond_dreiding.html, "hbond/dreiding/morse"_pair_hbond_dreiding.html, +"line/lj"_pair_line_lj.html, "lj/charmm/coul/charmm"_pair_charmm.html, "lj/charmm/coul/charmm/implicit"_pair_charmm.html, "lj/charmm/coul/long"_pair_charmm.html, @@ -667,6 +670,7 @@ potentials. Click on the style itself for a full description: "table"_pair_table.html, "tersoff"_pair_tersoff.html, "tersoff/zbl"_pair_tersoff_zbl.html, +"tri/lj"_pair_tri_lj.html, "yukawa"_pair_yukawa.html, "yukawa/colloid"_pair_yukawa_colloid.html :tb(c=4,ea=c) diff --git a/doc/fix.html b/doc/fix.html index c005536590..6d84638722 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -184,7 +184,6 @@ list of fix styles available in LAMMPS:

          • gcmc - grand canonical insertions/deletions
          • heat - add/subtract momentum-conserving heat
          • indent - impose force due to an indenter -
          • integrateU - Stokesian Dynamics evolution
          • langevin - Langevin temperature control
          • lineforce - constrain atoms to move in a line
          • momentum - zero the linear and/or angular momentum of a group of atoms diff --git a/doc/fix.txt b/doc/fix.txt index 6f59881200..6b824cf10c 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -179,7 +179,6 @@ list of fix styles available in LAMMPS: "gcmc"_fix_gcmc.html - grand canonical insertions/deletions "heat"_fix_heat.html - add/subtract momentum-conserving heat "indent"_fix_indent.html - impose force due to an indenter -"integrateU"_fix_integrateU.html - Stokesian Dynamics evolution "langevin"_fix_langevin.html - Langevin temperature control "lineforce"_fix_lineforce.html - constrain atoms to move in a line "momentum"_fix_momentum.html - zero the linear and/or angular momentum of a group of atoms diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html index fb5ffd893a..750a34767b 100644 --- a/doc/pair_coeff.html +++ b/doc/pair_coeff.html @@ -113,6 +113,7 @@ the pair_style command, and coefficients specified by the associated
          • pair_style gran/hooke/history - granular potential without history effects
          • pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
          • pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential +
          • pair_style line/lj - LJ potential between line segments
          • pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
          • pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
          • pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb @@ -142,6 +143,7 @@ the pair_style command, and coefficients specified by the associated
          • pair_style table - tabulated pair potential
          • pair_style tersoff - Tersoff 3-body potential
          • pair_style tersoff/zbl - Tersoff/ZBL 3-body potential +
          • pair_style tri/lj - LJ potential between triangles
          • pair_style yukawa - Yukawa potential
          • pair_style yukawa/colloid - screened Yukawa potential for finite-size particles
          diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt index 5a6c00a247..02aebc35f6 100644 --- a/doc/pair_coeff.txt +++ b/doc/pair_coeff.txt @@ -110,6 +110,7 @@ the pair_style command, and coefficients specified by the associated "pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects "pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential "pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential +"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments "pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb "pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent "pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb @@ -139,6 +140,7 @@ the pair_style command, and coefficients specified by the associated "pair_style table"_pair_table.html - tabulated pair potential "pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential "pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential +"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles "pair_style yukawa"_pair_yukawa.html - Yukawa potential "pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul diff --git a/doc/pair_style.html b/doc/pair_style.html index 0fd6871819..b00d2360e5 100644 --- a/doc/pair_style.html +++ b/doc/pair_style.html @@ -115,6 +115,7 @@ the pair_style command, and coefficients specified by the associated
        • pair_style gran/hooke/history - granular potential without history effects
        • pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
        • pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential +
        • pair_style line/lj - LJ potential between line segments
        • pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
        • pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
        • pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb @@ -144,6 +145,7 @@ the pair_style command, and coefficients specified by the associated
        • pair_style table - tabulated pair potential
        • pair_style tersoff - Tersoff 3-body potential
        • pair_style tersoff/zbl - Tersoff/ZBL 3-body potential +
        • pair_style tri/lj - LJ potential between triangles
        • pair_style yukawa - Yukawa potential
        • pair_style yukawa/colloid - screened Yukawa potential for finite-size particles
        diff --git a/doc/pair_style.txt b/doc/pair_style.txt index d7ae16d690..c450e3272a 100644 --- a/doc/pair_style.txt +++ b/doc/pair_style.txt @@ -112,6 +112,7 @@ the pair_style command, and coefficients specified by the associated "pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects "pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential "pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential +"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments "pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb "pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent "pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb @@ -141,6 +142,7 @@ the pair_style command, and coefficients specified by the associated "pair_style table"_pair_table.html - tabulated pair potential "pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential "pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential +"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles "pair_style yukawa"_pair_yukawa.html - Yukawa potential "pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul From 522e626bc9596dfb12853206afd6f48ca5c08b0c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:07:41 +0000 Subject: [PATCH 215/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7152 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/pair_line_lj.html | 117 ++++++++++++++++++++++++++++++++++++++++ doc/pair_line_lj.txt | 112 +++++++++++++++++++++++++++++++++++++++ doc/pair_tri_lj.html | 120 ++++++++++++++++++++++++++++++++++++++++++ doc/pair_tri_lj.txt | 115 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 464 insertions(+) create mode 100644 doc/pair_line_lj.html create mode 100644 doc/pair_line_lj.txt create mode 100644 doc/pair_tri_lj.html create mode 100644 doc/pair_tri_lj.txt diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html new file mode 100644 index 0000000000..205c5f3f91 --- /dev/null +++ b/doc/pair_line_lj.html @@ -0,0 +1,117 @@ + +
        LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
        + + + + + + +
        + +

        pair_style line command +

        +

        Syntax: +

        +
        pair_style line cutoff 
        +
        +

        cutoff = global cutoff for interactions (distance units) +

        +

        Examples: +

        +
        pair_style line 3.0
        +pair_coeff * * 1.0 1.0
        +pair_coeff 1 1 1.0 1.5 2.5 
        +
        +

        Description: +

        +

        Style line treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the pair_style +lj/cut doc page for the definition of Lennard-Jones +interactions. +

        +

        The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. +

        +

        The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. +

        +

        The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. +

        +

        For style line, the following coefficients must be defined for each +pair of atoms types via the pair_coeff command as in +the examples above, or in the data file or restart files read by the +read_data or read_restart +commands: +

        +
        • epsilon (energy units) +
        • sigma (distance units) +
        • cutoff (distance units) +
        +

        The last coefficient is optional. If not specified, the global cutoff +is used. +

        +
        + +

        Mixing, shift, table, tail correction, restart, rRESPA info: +

        +

        For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

        +

        This pair style does not support the pair_modify +shift, table, and tail options. +

        +

        This pair style does not write its information to binary restart +files. +

        +

        This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

        +
        + +

        Restrictions: +

        +

        This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

        +

        Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +atom_style line command. +

        +

        Related commands: +

        +

        pair_coeff +

        +

        Default: none +

        + diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt new file mode 100644 index 0000000000..160800250b --- /dev/null +++ b/doc/pair_line_lj.txt @@ -0,0 +1,112 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style line command :h3 + +[Syntax:] + +pair_style line cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style line 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {line} treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the "pair_style +lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones +interactions. + +The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. + +The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. + +The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. + +For style {line}, the following coefficients must be defined for each +pair of atoms types via the "pair_coeff"_pair_coeff.html command as in +the examples above, or in the data file or restart files read by the +"read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +"atom_style line"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html new file mode 100644 index 0000000000..931819e107 --- /dev/null +++ b/doc/pair_tri_lj.html @@ -0,0 +1,120 @@ + +
        LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
        + + + + + + +
        + +

        pair_style tri command +

        +

        Syntax: +

        +
        pair_style tri cutoff 
        +
        +

        cutoff = global cutoff for interactions (distance units) +

        +

        Examples: +

        +
        pair_style tri 3.0
        +pair_coeff * * 1.0 1.0
        +pair_coeff 1 1 1.0 1.5 2.5 
        +
        +

        Description: +

        +

        Style tri treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the pair_style lj/cut +doc page for the definition of Lennard-Jones interactions. +

        +

        The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. +

        +

        The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. +

        +

        The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. +

        +

        For style tri, the following coefficients must be defined for each +pair of atoms types via the pair_coeff command as in +the examples above, or in the data file or restart files read by the +read_data or read_restart +commands: +

        +
        • epsilon (energy units) +
        • sigma (distance units) +
        • cutoff (distance units) +
        +

        The last coefficient is optional. If not specified, the global cutoff +is used. +

        +
        + +

        Mixing, shift, table, tail correction, restart, rRESPA info: +

        +

        For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

        +

        This pair style does not support the pair_modify +shift, table, and tail options. +

        +

        This pair style does not write its information to binary restart +files. +

        +

        This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

        +
        + +

        Restrictions: +

        +

        This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

        +

        Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the atom_style +tri command. +

        +

        Related commands: +

        +

        pair_coeff +

        +

        Default: none +

        + diff --git a/doc/pair_tri_lj.txt b/doc/pair_tri_lj.txt new file mode 100644 index 0000000000..47aea453e5 --- /dev/null +++ b/doc/pair_tri_lj.txt @@ -0,0 +1,115 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style tri command :h3 + +[Syntax:] + +pair_style tri cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style tri 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {tri} treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html +doc page for the definition of Lennard-Jones interactions. + +The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. + +The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. + +The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. + +For style {tri}, the following coefficients must be defined for each +pair of atoms types via the "pair_coeff"_pair_coeff.html command as in +the examples above, or in the data file or restart files read by the +"read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the "atom_style +tri"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none From 8dfec21cf4494d2f01d49419e15ba75ec374309e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:09:12 +0000 Subject: [PATCH 216/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7153 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/atom_style.html | 3 +- doc/atom_style.txt | 3 +- doc/pair_line.html | 117 ------------------------------------------ doc/pair_line.txt | 112 ----------------------------------------- doc/pair_tri.html | 120 -------------------------------------------- doc/pair_tri.txt | 115 ------------------------------------------ 6 files changed, 2 insertions(+), 468 deletions(-) delete mode 100644 doc/pair_line.html delete mode 100644 doc/pair_line.txt delete mode 100644 doc/pair_tri.html delete mode 100644 doc/pair_tri.txt diff --git a/doc/atom_style.html b/doc/atom_style.html index 8b16f36569..77ca19b72f 100644 --- a/doc/atom_style.html +++ b/doc/atom_style.html @@ -140,8 +140,7 @@ section.

        The angle, bond, full, and molecular styles are part of the MOLECULAR package. The dipole style is part of the "dipole" -package. The ellipsoid, line, and tri styles are part of the -"asphere" package. The peri style is part of the PERI package for +package. The peri style is part of the PERI package for Peridynamics. The electron style is part of the USER-EFF package for electronic force fields. The meso style is part of the USER-SPH package for smoothed particle hydrodyanmics (SPH). diff --git a/doc/atom_style.txt b/doc/atom_style.txt index 5f85786a7a..ee0375927f 100644 --- a/doc/atom_style.txt +++ b/doc/atom_style.txt @@ -136,8 +136,7 @@ This command cannot be used after the simulation box is defined by a The {angle}, {bond}, {full}, and {molecular} styles are part of the MOLECULAR package. The {dipole} style is part of the "dipole" -package. The {ellipsoid}, {line}, and {tri} styles are part of the -"asphere" package. The {peri} style is part of the PERI package for +package. The {peri} style is part of the PERI package for Peridynamics. The {electron} style is part of the USER-EFF package for "electronic force fields"_pair_eff.html. The {meso} style is part of the USER-SPH package for smoothed particle hydrodyanmics (SPH). diff --git a/doc/pair_line.html b/doc/pair_line.html deleted file mode 100644 index 205c5f3f91..0000000000 --- a/doc/pair_line.html +++ /dev/null @@ -1,117 +0,0 @@ - -

        LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands -
        - - - - - - -
        - -

        pair_style line command -

        -

        Syntax: -

        -
        pair_style line cutoff 
        -
        -

        cutoff = global cutoff for interactions (distance units) -

        -

        Examples: -

        -
        pair_style line 3.0
        -pair_coeff * * 1.0 1.0
        -pair_coeff 1 1 1.0 1.5 2.5 
        -
        -

        Description: -

        -

        Style line treats particles which are line segments as a set of -small spherical particles that tile the line segment length as -explained below. Interactions between two line segments, each with N1 -and N2 spherical particles, are calculated as the pairwise sum of -N1*N2 Lennard-Jones interactions. Interactions between a line segment -with N spherical particles and a point particle are treated as the -pairwise sum of N Lennard-Jones interactions. See the pair_style -lj/cut doc page for the definition of Lennard-Jones -interactions. -

        -

        The cutoff distance for an interaction between 2 line segments, or -between a line segment and a point particle, is calculated from the -position of the line segment (its center), not between pairs of -individual spheres comprising the line segment. Thus an interaction -is either calculated in its entirety or not at all. -

        -

        The set of non-overlapping spherical particles that represent a line -segment, for purposes of this pair style, are generated in the -following manner. Their size is a function of the line segment length -and the specified sigma for that particle type. If a line segment has -a length L and is of type I, then the number of spheres N that -represent the segment is calculated as N = L/sigma_II, rounded up to -an integer value. Thus if L is not evenly divisibly by sigam_II, N is -incremented to include one extra sphere. In this case, the spheres -must be slightly smaller than sigma_II so as not to overlap, so a new -sigma-prime is chosen as the sphere diameter, such that L/N = -sigma-prime. Thus the line segment interacts with other segments or -point particles as a collection of N spheres of diameter sigma-prime, -evenly spaced along the line segment, so as to exactly cover its -length. -

        -

        The LJ interaction between 2 spheres on different line segments of -types I,J is computed with an arithmetic mixing of the sigma values of -the 2 spheres and using the specified epsilon value for I,J atom -types. Note that because the sigma values for line segment spheres is -computed using only sigma_II values, specific to the line segment's -type, this means that any specified sigma_IJ values (for I != J) are -effectively ignored. -

        -

        For style line, the following coefficients must be defined for each -pair of atoms types via the pair_coeff command as in -the examples above, or in the data file or restart files read by the -read_data or read_restart -commands: -

        -
        • epsilon (energy units) -
        • sigma (distance units) -
        • cutoff (distance units) -
        -

        The last coefficient is optional. If not specified, the global cutoff -is used. -

        -
        - -

        Mixing, shift, table, tail correction, restart, rRESPA info: -

        -

        For atom type pairs I,J and I != J, the epsilon and sigma coefficients -and cutoff distance for all of this pair style can be mixed. The -default mix value is geometric. See the "pair_modify" command for -details. -

        -

        This pair style does not support the pair_modify -shift, table, and tail options. -

        -

        This pair style does not write its information to binary restart -files. -

        -

        This pair style can only be used via the pair keyword of the -run_style respa command. It does not support the -inner, middle, outer keywords. -

        -
        - -

        Restrictions: -

        -

        This style is part of the ASPHERE package. It is only enabled if -LAMMPS was built with that package. See the Making -LAMMPS section for more info. -

        -

        Defining particles to be line segments so they participate in -line/line or line/particle interactions requires the use the -atom_style line command. -

        -

        Related commands: -

        -

        pair_coeff -

        -

        Default: none -

        - diff --git a/doc/pair_line.txt b/doc/pair_line.txt deleted file mode 100644 index 160800250b..0000000000 --- a/doc/pair_line.txt +++ /dev/null @@ -1,112 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -pair_style line command :h3 - -[Syntax:] - -pair_style line cutoff :pre - -cutoff = global cutoff for interactions (distance units) - -[Examples:] - -pair_style line 3.0 -pair_coeff * * 1.0 1.0 -pair_coeff 1 1 1.0 1.5 2.5 :pre - -[Description:] - -Style {line} treats particles which are line segments as a set of -small spherical particles that tile the line segment length as -explained below. Interactions between two line segments, each with N1 -and N2 spherical particles, are calculated as the pairwise sum of -N1*N2 Lennard-Jones interactions. Interactions between a line segment -with N spherical particles and a point particle are treated as the -pairwise sum of N Lennard-Jones interactions. See the "pair_style -lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones -interactions. - -The cutoff distance for an interaction between 2 line segments, or -between a line segment and a point particle, is calculated from the -position of the line segment (its center), not between pairs of -individual spheres comprising the line segment. Thus an interaction -is either calculated in its entirety or not at all. - -The set of non-overlapping spherical particles that represent a line -segment, for purposes of this pair style, are generated in the -following manner. Their size is a function of the line segment length -and the specified sigma for that particle type. If a line segment has -a length L and is of type I, then the number of spheres N that -represent the segment is calculated as N = L/sigma_II, rounded up to -an integer value. Thus if L is not evenly divisibly by sigam_II, N is -incremented to include one extra sphere. In this case, the spheres -must be slightly smaller than sigma_II so as not to overlap, so a new -sigma-prime is chosen as the sphere diameter, such that L/N = -sigma-prime. Thus the line segment interacts with other segments or -point particles as a collection of N spheres of diameter sigma-prime, -evenly spaced along the line segment, so as to exactly cover its -length. - -The LJ interaction between 2 spheres on different line segments of -types I,J is computed with an arithmetic mixing of the sigma values of -the 2 spheres and using the specified epsilon value for I,J atom -types. Note that because the sigma values for line segment spheres is -computed using only sigma_II values, specific to the line segment's -type, this means that any specified sigma_IJ values (for I != J) are -effectively ignored. - -For style {line}, the following coefficients must be defined for each -pair of atoms types via the "pair_coeff"_pair_coeff.html command as in -the examples above, or in the data file or restart files read by the -"read_data"_read_data.html or "read_restart"_read_restart.html -commands: - -epsilon (energy units) -sigma (distance units) -cutoff (distance units) :ul - -The last coefficient is optional. If not specified, the global cutoff -is used. - -:line - -[Mixing, shift, table, tail correction, restart, rRESPA info]: - -For atom type pairs I,J and I != J, the epsilon and sigma coefficients -and cutoff distance for all of this pair style can be mixed. The -default mix value is {geometric}. See the "pair_modify" command for -details. - -This pair style does not support the "pair_modify"_pair_modify.html -shift, table, and tail options. - -This pair style does not write its information to "binary restart -files"_restart.html. - -This pair style can only be used via the {pair} keyword of the -"run_style respa"_run_style.html command. It does not support the -{inner}, {middle}, {outer} keywords. - -:line - -[Restrictions:] - -This style is part of the ASPHERE package. It is only enabled if -LAMMPS was built with that package. See the "Making -LAMMPS"_Section_start.html#2_3 section for more info. - -Defining particles to be line segments so they participate in -line/line or line/particle interactions requires the use the -"atom_style line"_atom_style.html command. - -[Related commands:] - -"pair_coeff"_pair_coeff.html - -[Default:] none diff --git a/doc/pair_tri.html b/doc/pair_tri.html deleted file mode 100644 index 931819e107..0000000000 --- a/doc/pair_tri.html +++ /dev/null @@ -1,120 +0,0 @@ - -
        LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands -
        - - - - - - -
        - -

        pair_style tri command -

        -

        Syntax: -

        -
        pair_style tri cutoff 
        -
        -

        cutoff = global cutoff for interactions (distance units) -

        -

        Examples: -

        -
        pair_style tri 3.0
        -pair_coeff * * 1.0 1.0
        -pair_coeff 1 1 1.0 1.5 2.5 
        -
        -

        Description: -

        -

        Style tri treats particles which are triangles as a set of small -spherical particles that tile the triangle surface as explained below. -Interactions between two triangles, each with N1 and N2 spherical -particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones -interactions. Interactions between a triangle with N spherical -particles and a point particle are treated as the pairwise sum of N -Lennard-Jones interactions. See the pair_style lj/cut -doc page for the definition of Lennard-Jones interactions. -

        -

        The cutoff distance for an interaction between 2 triangles, or between -a triangle and a point particle, is calculated from the position of -the triangle (its centroid), not between pairs of individual spheres -comprising the triangle. Thus an interaction is either calculated in -its entirety or not at all. -

        -

        The set of non-overlapping spherical particles that represent a -triangle, for purposes of this pair style, are generated in the -following manner. Assume the triangle is of type I, and sigma_II has -been specified. We want a set of spheres with centers in the plane of -the triangle, none of them larger in diameter than sigma_II, which -completely cover the triangle's area, but with minimial overlap and a -minimal total number of spheres. This is done in a recursive manner. -Place a sphere at the centroid of the original triangle. Calculate -what diameter it must have to just cover all 3 corner points of the -triangle. If that diameter is equal to or smaller than sigma_II, then -include a sphere of the calculated diameter in the set of covering -spheres. It the diameter is larger than sigma_II, then split the -triangle into 2 triangles by bisecting its longest side. Repeat the -process on each sub-triangle, recursing as far as needed to generate a -set of covering spheres. When finished, the original criteria are -met, and the set of covering spheres shoule be near minimal in number -and overlap, at least for input triangles with a reasonable -aspect-ratio. -

        -

        The LJ interaction between 2 spheres on different triangles of types -I,J is computed with an arithmetic mixing of the sigma values of the 2 -spheres and using the specified epsilon value for I,J atom types. -Note that because the sigma values for triangles spheres is computed -using only sigma_II values, specific to the triangles's type, this -means that any specified sigma_IJ values (for I != J) are effectively -ignored. -

        -

        For style tri, the following coefficients must be defined for each -pair of atoms types via the pair_coeff command as in -the examples above, or in the data file or restart files read by the -read_data or read_restart -commands: -

        -
        • epsilon (energy units) -
        • sigma (distance units) -
        • cutoff (distance units) -
        -

        The last coefficient is optional. If not specified, the global cutoff -is used. -

        -
        - -

        Mixing, shift, table, tail correction, restart, rRESPA info: -

        -

        For atom type pairs I,J and I != J, the epsilon and sigma coefficients -and cutoff distance for all of this pair style can be mixed. The -default mix value is geometric. See the "pair_modify" command for -details. -

        -

        This pair style does not support the pair_modify -shift, table, and tail options. -

        -

        This pair style does not write its information to binary restart -files. -

        -

        This pair style can only be used via the pair keyword of the -run_style respa command. It does not support the -inner, middle, outer keywords. -

        -
        - -

        Restrictions: -

        -

        This style is part of the ASPHERE package. It is only enabled if -LAMMPS was built with that package. See the Making -LAMMPS section for more info. -

        -

        Defining particles to be triangles so they participate in tri/tri or -tri/particle interactions requires the use the atom_style -tri command. -

        -

        Related commands: -

        -

        pair_coeff -

        -

        Default: none -

        - diff --git a/doc/pair_tri.txt b/doc/pair_tri.txt deleted file mode 100644 index 47aea453e5..0000000000 --- a/doc/pair_tri.txt +++ /dev/null @@ -1,115 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -pair_style tri command :h3 - -[Syntax:] - -pair_style tri cutoff :pre - -cutoff = global cutoff for interactions (distance units) - -[Examples:] - -pair_style tri 3.0 -pair_coeff * * 1.0 1.0 -pair_coeff 1 1 1.0 1.5 2.5 :pre - -[Description:] - -Style {tri} treats particles which are triangles as a set of small -spherical particles that tile the triangle surface as explained below. -Interactions between two triangles, each with N1 and N2 spherical -particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones -interactions. Interactions between a triangle with N spherical -particles and a point particle are treated as the pairwise sum of N -Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html -doc page for the definition of Lennard-Jones interactions. - -The cutoff distance for an interaction between 2 triangles, or between -a triangle and a point particle, is calculated from the position of -the triangle (its centroid), not between pairs of individual spheres -comprising the triangle. Thus an interaction is either calculated in -its entirety or not at all. - -The set of non-overlapping spherical particles that represent a -triangle, for purposes of this pair style, are generated in the -following manner. Assume the triangle is of type I, and sigma_II has -been specified. We want a set of spheres with centers in the plane of -the triangle, none of them larger in diameter than sigma_II, which -completely cover the triangle's area, but with minimial overlap and a -minimal total number of spheres. This is done in a recursive manner. -Place a sphere at the centroid of the original triangle. Calculate -what diameter it must have to just cover all 3 corner points of the -triangle. If that diameter is equal to or smaller than sigma_II, then -include a sphere of the calculated diameter in the set of covering -spheres. It the diameter is larger than sigma_II, then split the -triangle into 2 triangles by bisecting its longest side. Repeat the -process on each sub-triangle, recursing as far as needed to generate a -set of covering spheres. When finished, the original criteria are -met, and the set of covering spheres shoule be near minimal in number -and overlap, at least for input triangles with a reasonable -aspect-ratio. - -The LJ interaction between 2 spheres on different triangles of types -I,J is computed with an arithmetic mixing of the sigma values of the 2 -spheres and using the specified epsilon value for I,J atom types. -Note that because the sigma values for triangles spheres is computed -using only sigma_II values, specific to the triangles's type, this -means that any specified sigma_IJ values (for I != J) are effectively -ignored. - -For style {tri}, the following coefficients must be defined for each -pair of atoms types via the "pair_coeff"_pair_coeff.html command as in -the examples above, or in the data file or restart files read by the -"read_data"_read_data.html or "read_restart"_read_restart.html -commands: - -epsilon (energy units) -sigma (distance units) -cutoff (distance units) :ul - -The last coefficient is optional. If not specified, the global cutoff -is used. - -:line - -[Mixing, shift, table, tail correction, restart, rRESPA info]: - -For atom type pairs I,J and I != J, the epsilon and sigma coefficients -and cutoff distance for all of this pair style can be mixed. The -default mix value is {geometric}. See the "pair_modify" command for -details. - -This pair style does not support the "pair_modify"_pair_modify.html -shift, table, and tail options. - -This pair style does not write its information to "binary restart -files"_restart.html. - -This pair style can only be used via the {pair} keyword of the -"run_style respa"_run_style.html command. It does not support the -{inner}, {middle}, {outer} keywords. - -:line - -[Restrictions:] - -This style is part of the ASPHERE package. It is only enabled if -LAMMPS was built with that package. See the "Making -LAMMPS"_Section_start.html#2_3 section for more info. - -Defining particles to be triangles so they participate in tri/tri or -tri/particle interactions requires the use the "atom_style -tri"_atom_style.html command. - -[Related commands:] - -"pair_coeff"_pair_coeff.html - -[Default:] none From fd155252ea24a3d24dd35f6e674b43981e718b5b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:09:45 +0000 Subject: [PATCH 217/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7154 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/pair_line_lj.cpp | 444 ++++++++++++++++++++++++ src/ASPHERE/pair_line_lj.h | 61 ++++ src/ASPHERE/pair_tri_lj.cpp | 637 +++++++++++++++++++++++++++++++++++ src/ASPHERE/pair_tri_lj.h | 61 ++++ 4 files changed, 1203 insertions(+) create mode 100644 src/ASPHERE/pair_line_lj.cpp create mode 100644 src/ASPHERE/pair_line_lj.h create mode 100644 src/ASPHERE/pair_tri_lj.cpp create mode 100644 src/ASPHERE/pair_tri_lj.h diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp new file mode 100644 index 0000000000..4a3902c888 --- /dev/null +++ b/src/ASPHERE/pair_line_lj.cpp @@ -0,0 +1,444 @@ +/* ---------------------------------------------------------------------- + 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_line.h" +#include "atom.h" +#include "atom_vec_line.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +PairLine::PairLine(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecLine *) atom->style_match("line"); + if (!avec) error->all(FLERR,"Pair line requires atom style line"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairLine::~PairLine() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLine::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + int *line = atom->line; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + 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]) continue; + + // line/line interactions = NxN particles + + evdwl = 0.0; + if (line[i] >= 0 && line[j] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + } + + // line/particle interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[i] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + } + } + + // particle/line interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[j] >= 0) { + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + + if (newton_pair || j < nlocal) { + f[j][0] += fj[0]; + f[j][1] += fj[1]; + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairLine::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairLine::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(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 PairLine::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairLine::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + discretize line segment I into N sub-segments no more than sigma in length + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairLine::discretize(int i, double sigma) +{ + AtomVecLine::Bonus *bonus = avec->bonus; + double length = bonus[atom->line[i]].length; + double theta = bonus[atom->line[i]].theta; + int n = static_cast (length/sigma) + 1; + dnum[i] = n; + dfirst[i] = ndiscrete; + + if (ndiscrete + n > dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + + double *x = atom->x[i]; + sigma = length/n; + double delta; + + for (int m = 0; m < n; m++) { + delta = -0.5 + (2*m+1)/(2.0*n); + discrete[ndiscrete].dx = delta*length*cos(theta); + discrete[ndiscrete].dy = delta*length*sin(theta); + discrete[ndiscrete].sigma = sigma; + ndiscrete++; + } +} diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h new file mode 100644 index 0000000000..6598bfe6c1 --- /dev/null +++ b/src/ASPHERE/pair_line_lj.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(line,PairLine) + +#else + +#ifndef LMP_PAIR_LINE_H +#define LMP_PAIR_LINE_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairLine : public Pair { + public: + PairLine(class LAMMPS *); + ~PairLine(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecLine *avec; + + struct Discrete { + double dx,dy; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double); +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp new file mode 100644 index 0000000000..0a40b8fb06 --- /dev/null +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -0,0 +1,637 @@ +/* ---------------------------------------------------------------------- + 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_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_tri.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 20 + +/* ---------------------------------------------------------------------- */ + +PairTri::PairTri(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecTri *) atom->style_match("tri"); + if (!avec) error->all(FLERR,"Pair tri requires atom style tri"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairTri::~PairTri() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTri::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double dxi,dxj,dyi,dyj,dzi,dzj; + double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3]; + double dc1[3],dc2[3],dc3[3]; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + AtomVecTri::Bonus *bonus = avec->bonus; + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + int *tri = atom->tri; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + 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]) continue; + + // tri/tri interactions = NxN particles + // c1,c2,c3 = corner pts of triangle I or J + + evdwl = 0.0; + if (tri[i] >= 0 && tri[j] >= 0) { + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][0] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + } + + // tri/particle interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle I + + } else if (tri[i] >= 0) { + + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + xj[2] = x[j][2]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][2] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + } + } + + // particle/tri interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle J + + } else if (tri[j] >= 0) { + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairTri::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairTri::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(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 PairTri::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairTri::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 2 tris via bisecting longest side + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairTri::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double c1c2[3],c2c3[3],c1c3[3]; + + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 2 sub-triangles and recurse + + double c12[3],c23[3],c13[3],mid[3]; + + MathExtra::sub3(c2,c3,c23); + len1sq = MathExtra::lensq3(c23); + MathExtra::sub3(c1,c3,c13); + len2sq = MathExtra::lensq3(c13); + MathExtra::sub3(c1,c2,c12); + len3sq = MathExtra::lensq3(c12); + + double maxsq = MAX(len1sq,len2sq); + maxsq = MAX(maxsq,len3sq); + + if (len1sq == maxsq) { + MathExtra::add3(c2,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c1,c2,mid); + discretize(i,sigma,c1,c3,mid); + } else if (len2sq == maxsq) { + MathExtra::add3(c1,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c2,c1,mid); + discretize(i,sigma,c2,c3,mid); + } else { + MathExtra::add3(c1,c2,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c3,c1,mid); + discretize(i,sigma,c3,c2,mid); + } +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 6 tris via centroid + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +/* +void PairTri::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 6 sub-triangles and recurse + + double c1c2mid[3],c2c3mid[3],c1c3mid[3]; + + MathExtra::add3(c1,c2,c1c2mid); + MathExtra::scale3(0.5,c1c2mid); + MathExtra::add3(c2,c3,c2c3mid); + MathExtra::scale3(0.5,c2c3mid); + MathExtra::add3(c1,c3,c1c3mid); + MathExtra::scale3(0.5,c1c3mid); + + discretize(i,sigma,c1,c1c2mid,centroid); + discretize(i,sigma,c1,c1c3mid,centroid); + discretize(i,sigma,c2,c2c3mid,centroid); + discretize(i,sigma,c2,c1c2mid,centroid); + discretize(i,sigma,c3,c1c3mid,centroid); + discretize(i,sigma,c3,c2c3mid,centroid); +} + +*/ diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h new file mode 100644 index 0000000000..fd1fe08bac --- /dev/null +++ b/src/ASPHERE/pair_tri_lj.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tri,PairTri) + +#else + +#ifndef LMP_PAIR_TRI_H +#define LMP_PAIR_TRI_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairTri : public Pair { + public: + PairTri(class LAMMPS *); + ~PairTri(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecTri *avec; + + struct Discrete { + double dx,dy,dz; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double, double *, double *, double *); +}; + +} + +#endif +#endif From 8287969efa327bc5096118df84ffe8d0fdfa6c4e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:10:28 +0000 Subject: [PATCH 218/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7155 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/Install.sh | 16 +- src/ASPHERE/pair_line.cpp | 444 -------------------------- src/ASPHERE/pair_line.h | 61 ---- src/ASPHERE/pair_tri.cpp | 637 -------------------------------------- src/ASPHERE/pair_tri.h | 61 ---- 5 files changed, 8 insertions(+), 1211 deletions(-) delete mode 100644 src/ASPHERE/pair_line.cpp delete mode 100644 src/ASPHERE/pair_line.h delete mode 100644 src/ASPHERE/pair_tri.cpp delete mode 100644 src/ASPHERE/pair_tri.h diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index 2f6f974332..1cc7a4b61d 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -12,9 +12,9 @@ if (test $1 = 1) then cp fix_nve_tri.cpp .. cp fix_nvt_asphere.cpp .. cp pair_gayberne.cpp .. - cp pair_line.cpp .. + cp pair_line_lj.cpp .. cp pair_resquared.cpp .. - cp pair_tri.cpp .. + cp pair_tri_Lj.cpp .. cp compute_erotate_asphere.h .. cp compute_temp_asphere.h .. @@ -26,9 +26,9 @@ if (test $1 = 1) then cp fix_nve_tri.h .. cp fix_nvt_asphere.h .. cp pair_gayberne.h .. - cp pair_line.h .. + cp pair_line_lj.h .. cp pair_resquared.h .. - cp pair_tri.h .. + cp pair_tri_lj.h .. elif (test $1 = 0) then @@ -42,9 +42,9 @@ elif (test $1 = 0) then rm -f ../fix_nve_tri.cpp rm -f ../fix_nvt_asphere.cpp rm -f ../pair_gayberne.cpp - rm -f ../pair_line.cpp + rm -f ../pair_line_lj.cpp rm -f ../pair_resquared.cpp - rm -f ../pair_tri.cpp + rm -f ../pair_tri_lj.cpp rm -f ../compute_erotate_asphere.h rm -f ../compute_temp_asphere.h @@ -56,8 +56,8 @@ elif (test $1 = 0) then rm -f ../fix_nve_tri.h rm -f ../fix_nvt_asphere.h rm -f ../pair_gayberne.h - rm -f ../pair_line.h + rm -f ../pair_line_lj.h rm -f ../pair_resquared.h - rm -f ../pair_tri.h + rm -f ../pair_tri_lj.h fi diff --git a/src/ASPHERE/pair_line.cpp b/src/ASPHERE/pair_line.cpp deleted file mode 100644 index 4a3902c888..0000000000 --- a/src/ASPHERE/pair_line.cpp +++ /dev/null @@ -1,444 +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 "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_line.h" -#include "atom.h" -#include "atom_vec_line.h" -#include "force.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define DELTA 10000 - -/* ---------------------------------------------------------------------- */ - -PairLine::PairLine(LAMMPS *lmp) : Pair(lmp) -{ - avec = (AtomVecLine *) atom->style_match("line"); - if (!avec) error->all(FLERR,"Pair line requires atom style line"); - - dmax = nmax = 0; - discrete = NULL; - dnum = dfirst = NULL; - - single_enable = 0; -} - -/* ---------------------------------------------------------------------- */ - -PairLine::~PairLine() -{ - memory->sfree(discrete); - memory->destroy(dnum); - memory->destroy(dfirst); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLine::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum,itype,jtype; - int ni,nj,npi,npj,ifirst,jfirst; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; - double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj; - int *ilist,*jlist,*numneigh,**firstneigh; - - evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - double **x = atom->x; - double **f = atom->f; - double **torque = atom->torque; - int *line = atom->line; - int *type = atom->type; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - int newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // grow discrete list if necessary and initialize - - if (nall > nmax) { - memory->destroy(dnum); - memory->destroy(dfirst); - memory->create(dnum,nall,"pair:dnum"); - memory->create(dfirst,nall,"pair:dfirst"); - } - for (i = 0; i < nall; i++) dnum[i] = 0; - ndiscrete = 0; - - // 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]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - - 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]) continue; - - // line/line interactions = NxN particles - - evdwl = 0.0; - if (line[i] >= 0 && line[j] >= 0) { - if (dnum[i] == 0) discretize(i,sigma[itype][itype]); - npi = dnum[i]; - ifirst = dfirst[i]; - if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); - npj = dnum[j]; - jfirst = dfirst[j]; - - for (ni = 0; ni < npi; ni++) { - dxi = discrete[ifirst+ni].dx; - dyi = discrete[ifirst+ni].dy; - - for (nj = 0; nj < npj; nj++) { - dxj = discrete[jfirst+nj].dx; - dyj = discrete[jfirst+nj].dy; - - xi[0] = x[i][0] + dxi; - xi[1] = x[i][1] + dyi; - xj[0] = x[j][0] + dxj; - xj[1] = x[j][1] + dyj; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - rsq = delx*delx + dely*dely; - - sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - torque[i][2] += dxi*fi[1] - dyi*fi[0]; - - if (newton_pair || j < nlocal) { - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - f[j][0] += fj[0]; - f[j][1] += fj[1]; - torque[j][2] += dxj*fj[1] - dyj*fj[0]; - } - } - } - - // line/particle interaction = Nx1 particles - // convert line into Np particles based on sigma and line length - - } else if (line[i] >= 0) { - if (dnum[i] == 0) discretize(i,sigma[itype][itype]); - npi = dnum[i]; - ifirst = dfirst[i]; - - for (ni = 0; ni < npi; ni++) { - dxi = discrete[ifirst+ni].dx; - dyi = discrete[ifirst+ni].dy; - - xi[0] = x[i][0] + dxi; - xi[1] = x[i][1] + dyi; - xj[0] = x[j][0]; - xj[1] = x[j][1]; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - rsq = delx*delx + dely*dely; - - sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - torque[i][2] += dxi*fi[1] - dyi*fi[0]; - - if (newton_pair || j < nlocal) { - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - f[j][0] += fj[0]; - f[j][1] += fj[1]; - } - } - - // particle/line interaction = Nx1 particles - // convert line into Np particles based on sigma and line length - - } else if (line[j] >= 0) { - if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); - npj = dnum[j]; - jfirst = dfirst[j]; - - for (nj = 0; nj < npj; nj++) { - dxj = discrete[jfirst+nj].dx; - dyj = discrete[jfirst+nj].dy; - - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xj[0] = x[j][0] + dxj; - xj[1] = x[j][1] + dyj; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - rsq = delx*delx + dely*dely; - - sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - - if (newton_pair || j < nlocal) { - f[j][0] += fj[0]; - f[j][1] += fj[1]; - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - torque[j][2] += dxj*fj[1] - dyj*fj[0]; - } - } - - // particle/particle interaction = 1x1 particles - - } else { - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - fpair = forcelj*r2inv; - - if (eflag) - evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - - f[i][0] += delx*fpair; - f[i][1] += dely*fpair; - f[i][2] += delz*fpair; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fpair; - f[j][1] -= dely*fpair; - f[j][2] -= delz*fpair; - } - } - - if (evflag) ev_tally(i,j,nlocal,newton_pair, - evdwl,0.0,fpair,delx,dely,delz); - } - } - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairLine::allocate() -{ - allocated = 1; - int n = atom->ntypes; - - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; - - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(epsilon,n+1,n+1,"pair:epsilon"); - memory->create(sigma,n+1,n+1,"pair:sigma"); - memory->create(lj1,n+1,n+1,"pair:lj1"); - memory->create(lj2,n+1,n+1,"pair:lj2"); - memory->create(lj3,n+1,n+1,"pair:lj3"); - memory->create(lj4,n+1,n+1,"pair:lj4"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairLine::settings(int narg, char **arg) -{ - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); - - cut_global = force->numeric(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 PairLine::coeff(int narg, char **arg) -{ - if (narg < 4 || narg > 5) - error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); - double sigma_one = force->numeric(arg[3]); - - double cut_one = cut_global; - if (narg == 5) cut_one = force->numeric(arg[4]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - epsilon[i][j] = epsilon_one; - sigma[i][j] = sigma_one; - cut[i][j] = cut_one; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairLine::init_one(int i, int j) -{ - if (setflag[i][j] == 0) { - epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], - sigma[i][i],sigma[j][j]); - sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); - cut[i][j] = mix_distance(cut[i][i],cut[j][j]); - } - - lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); - lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); - lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); - lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); - - epsilon[j][i] = epsilon[i][j]; - sigma[j][i] = sigma[i][j]; - lj1[j][i] = lj1[i][j]; - lj2[j][i] = lj2[i][j]; - lj3[j][i] = lj3[i][j]; - lj4[j][i] = lj4[i][j]; - - return cut[i][j]; -} - -/* ---------------------------------------------------------------------- - discretize line segment I into N sub-segments no more than sigma in length - store new discrete particles in Discrete list -------------------------------------------------------------------------- */ - -void PairLine::discretize(int i, double sigma) -{ - AtomVecLine::Bonus *bonus = avec->bonus; - double length = bonus[atom->line[i]].length; - double theta = bonus[atom->line[i]].theta; - int n = static_cast (length/sigma) + 1; - dnum[i] = n; - dfirst[i] = ndiscrete; - - if (ndiscrete + n > dmax) { - dmax += DELTA; - discrete = (Discrete *) - memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); - } - - double *x = atom->x[i]; - sigma = length/n; - double delta; - - for (int m = 0; m < n; m++) { - delta = -0.5 + (2*m+1)/(2.0*n); - discrete[ndiscrete].dx = delta*length*cos(theta); - discrete[ndiscrete].dy = delta*length*sin(theta); - discrete[ndiscrete].sigma = sigma; - ndiscrete++; - } -} diff --git a/src/ASPHERE/pair_line.h b/src/ASPHERE/pair_line.h deleted file mode 100644 index 6598bfe6c1..0000000000 --- a/src/ASPHERE/pair_line.h +++ /dev/null @@ -1,61 +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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(line,PairLine) - -#else - -#ifndef LMP_PAIR_LINE_H -#define LMP_PAIR_LINE_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairLine : public Pair { - public: - PairLine(class LAMMPS *); - ~PairLine(); - void compute(int, int); - void settings(int, char **); - void coeff(int, char **); - double init_one(int, int); - - protected: - double cut_global; - double **cut; - double **epsilon,**sigma; - double **lj1,**lj2,**lj3,**lj4; - class AtomVecLine *avec; - - struct Discrete { - double dx,dy; - double sigma; - }; - Discrete *discrete; // list of all discretes for all lines - int ndiscrete; // number of discretes in list - int dmax; // allocated size of discrete list - int *dnum; // number of discretes per line, 0 if uninit - int *dfirst; // index of first discrete per each line - int nmax; // allocated size of dnum,dfirst vectors - - void allocate(); - void discretize(int, double); -}; - -} - -#endif -#endif diff --git a/src/ASPHERE/pair_tri.cpp b/src/ASPHERE/pair_tri.cpp deleted file mode 100644 index 0a40b8fb06..0000000000 --- a/src/ASPHERE/pair_tri.cpp +++ /dev/null @@ -1,637 +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 "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_tri.h" -#include "math_extra.h" -#include "atom.h" -#include "atom_vec_tri.h" -#include "force.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define DELTA 20 - -/* ---------------------------------------------------------------------- */ - -PairTri::PairTri(LAMMPS *lmp) : Pair(lmp) -{ - avec = (AtomVecTri *) atom->style_match("tri"); - if (!avec) error->all(FLERR,"Pair tri requires atom style tri"); - - dmax = nmax = 0; - discrete = NULL; - dnum = dfirst = NULL; - - single_enable = 0; -} - -/* ---------------------------------------------------------------------- */ - -PairTri::~PairTri() -{ - memory->sfree(discrete); - memory->destroy(dnum); - memory->destroy(dfirst); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - } -} - -/* ---------------------------------------------------------------------- */ - -void PairTri::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum,itype,jtype; - int ni,nj,npi,npj,ifirst,jfirst; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; - double dxi,dxj,dyi,dyj,dzi,dzj; - double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3]; - double dc1[3],dc2[3],dc3[3]; - int *ilist,*jlist,*numneigh,**firstneigh; - - evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - AtomVecTri::Bonus *bonus = avec->bonus; - double **x = atom->x; - double **f = atom->f; - double **torque = atom->torque; - int *tri = atom->tri; - int *type = atom->type; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - int newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // grow discrete list if necessary and initialize - - if (nall > nmax) { - memory->destroy(dnum); - memory->destroy(dfirst); - memory->create(dnum,nall,"pair:dnum"); - memory->create(dfirst,nall,"pair:dfirst"); - } - for (i = 0; i < nall; i++) dnum[i] = 0; - ndiscrete = 0; - - // 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]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - - 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]) continue; - - // tri/tri interactions = NxN particles - // c1,c2,c3 = corner pts of triangle I or J - - evdwl = 0.0; - if (tri[i] >= 0 && tri[j] >= 0) { - if (dnum[i] == 0) { - MathExtra::quat_to_mat(bonus[tri[i]].quat,p); - MathExtra::matvec(p,bonus[tri[i]].c1,dc1); - MathExtra::matvec(p,bonus[tri[i]].c2,dc2); - MathExtra::matvec(p,bonus[tri[i]].c3,dc3); - dfirst[i] = ndiscrete; - discretize(i,sigma[itype][itype],dc1,dc2,dc3); - dnum[i] = ndiscrete - dfirst[i]; - } - npi = dnum[i]; - ifirst = dfirst[i]; - - if (dnum[j] == 0) { - MathExtra::quat_to_mat(bonus[tri[j]].quat,p); - MathExtra::matvec(p,bonus[tri[j]].c1,dc1); - MathExtra::matvec(p,bonus[tri[j]].c2,dc2); - MathExtra::matvec(p,bonus[tri[j]].c3,dc3); - dfirst[j] = ndiscrete; - discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); - dnum[j] = ndiscrete - dfirst[j]; - } - npj = dnum[j]; - jfirst = dfirst[j]; - - for (ni = 0; ni < npi; ni++) { - dxi = discrete[ifirst+ni].dx; - dyi = discrete[ifirst+ni].dy; - dzi = discrete[ifirst+ni].dz; - - for (nj = 0; nj < npj; nj++) { - dxj = discrete[jfirst+nj].dx; - dyj = discrete[jfirst+nj].dy; - dzj = discrete[jfirst+nj].dz; - - xi[0] = x[i][0] + dxi; - xi[1] = x[i][1] + dyi; - xi[2] = x[i][2] + dzi; - xj[0] = x[j][0] + dxj; - xj[1] = x[j][1] + dyj; - xj[2] = x[j][2] + dzj; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - delz = xi[2] - xj[2]; - rsq = delx*delx + dely*dely + delz*delz; - - sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - fi[2] = delz*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - f[i][2] += fi[2]; - ti[0] = dyi*fi[2] - dzi*fi[1]; - ti[1] = dzi*fi[0] - dxi*fi[2]; - ti[2] = dxi*fi[1] - dyi*fi[0]; - torque[i][0] += ti[0]; - torque[i][1] += ti[1]; - torque[i][2] += ti[2]; - - if (newton_pair || j < nlocal) { - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - fj[2] = -delz*fpair; - f[j][0] += fj[0]; - f[j][1] += fj[1]; - f[j][2] += fj[2]; - tj[0] = dyj*fj[2] - dzj*fj[1]; - tj[1] = dzj*fj[0] - dxj*fj[2]; - tj[2] = dxj*fj[1] - dyj*fj[0]; - torque[j][0] += tj[0]; - torque[j][1] += tj[1]; - torque[j][2] += tj[2]; - } - } - } - - // tri/particle interaction = Nx1 particles - // c1,c2,c3 = corner pts of triangle I - - } else if (tri[i] >= 0) { - - if (dnum[i] == 0) { - MathExtra::quat_to_mat(bonus[tri[i]].quat,p); - MathExtra::matvec(p,bonus[tri[i]].c1,dc1); - MathExtra::matvec(p,bonus[tri[i]].c2,dc2); - MathExtra::matvec(p,bonus[tri[i]].c3,dc3); - dfirst[i] = ndiscrete; - discretize(i,sigma[itype][itype],dc1,dc2,dc3); - dnum[i] = ndiscrete - dfirst[i]; - } - npi = dnum[i]; - ifirst = dfirst[i]; - - for (ni = 0; ni < npi; ni++) { - dxi = discrete[ifirst+ni].dx; - dyi = discrete[ifirst+ni].dy; - dzi = discrete[ifirst+ni].dz; - - xi[0] = x[i][0] + dxi; - xi[1] = x[i][1] + dyi; - xi[2] = x[i][2] + dzi; - xj[0] = x[j][0]; - xj[1] = x[j][1]; - xj[2] = x[j][2]; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - delz = xi[2] - xj[2]; - rsq = delx*delx + dely*dely + delz*delz; - - sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - fi[2] = delz*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - f[i][2] += fi[2]; - ti[0] = dyi*fi[2] - dzi*fi[1]; - ti[1] = dzi*fi[0] - dxi*fi[2]; - ti[2] = dxi*fi[1] - dyi*fi[0]; - torque[i][2] += ti[0]; - torque[i][1] += ti[1]; - torque[i][2] += ti[2]; - - if (newton_pair || j < nlocal) { - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - fj[2] = -delz*fpair; - f[j][0] += fj[0]; - f[j][1] += fj[1]; - f[j][2] += fj[2]; - } - } - - // particle/tri interaction = Nx1 particles - // c1,c2,c3 = corner pts of triangle J - - } else if (tri[j] >= 0) { - if (dnum[j] == 0) { - MathExtra::quat_to_mat(bonus[tri[j]].quat,p); - MathExtra::matvec(p,bonus[tri[j]].c1,dc1); - MathExtra::matvec(p,bonus[tri[j]].c2,dc2); - MathExtra::matvec(p,bonus[tri[j]].c3,dc3); - dfirst[j] = ndiscrete; - discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); - dnum[j] = ndiscrete - dfirst[j]; - } - npj = dnum[j]; - jfirst = dfirst[j]; - - for (nj = 0; nj < npj; nj++) { - dxj = discrete[jfirst+nj].dx; - dyj = discrete[jfirst+nj].dy; - dzj = discrete[jfirst+nj].dz; - - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; - xj[0] = x[j][0] + dxj; - xj[1] = x[j][1] + dyj; - xj[2] = x[j][2] + dzj; - - delx = xi[0] - xj[0]; - dely = xi[1] - xj[1]; - delz = xi[2] - xj[2]; - rsq = delx*delx + dely*dely + delz*delz; - - sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); - sig3 = sig*sig*sig; - term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; - term1 = 2.0 * term2 * sig3*sig3; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (term1*r6inv - term2); - fpair = forcelj*r2inv; - - if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); - - fi[0] = delx*fpair; - fi[1] = dely*fpair; - fi[2] = delz*fpair; - f[i][0] += fi[0]; - f[i][1] += fi[1]; - f[i][2] += fi[2]; - - if (newton_pair || j < nlocal) { - fj[0] = -delx*fpair; - fj[1] = -dely*fpair; - fj[2] = -delz*fpair; - f[j][0] += fj[0]; - f[j][1] += fj[1]; - f[j][2] += fj[2]; - tj[0] = dyj*fj[2] - dzj*fj[1]; - tj[1] = dzj*fj[0] - dxj*fj[2]; - tj[2] = dxj*fj[1] - dyj*fj[0]; - torque[j][0] += tj[0]; - torque[j][1] += tj[1]; - torque[j][2] += tj[2]; - } - } - - // particle/particle interaction = 1x1 particles - - } else { - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - fpair = forcelj*r2inv; - - if (eflag) - evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - - f[i][0] += delx*fpair; - f[i][1] += dely*fpair; - f[i][2] += delz*fpair; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fpair; - f[j][1] -= dely*fpair; - f[j][2] -= delz*fpair; - } - } - - if (evflag) ev_tally(i,j,nlocal,newton_pair, - evdwl,0.0,fpair,delx,dely,delz); - } - } - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairTri::allocate() -{ - allocated = 1; - int n = atom->ntypes; - - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; - - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(epsilon,n+1,n+1,"pair:epsilon"); - memory->create(sigma,n+1,n+1,"pair:sigma"); - memory->create(lj1,n+1,n+1,"pair:lj1"); - memory->create(lj2,n+1,n+1,"pair:lj2"); - memory->create(lj3,n+1,n+1,"pair:lj3"); - memory->create(lj4,n+1,n+1,"pair:lj4"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairTri::settings(int narg, char **arg) -{ - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); - - cut_global = force->numeric(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 PairTri::coeff(int narg, char **arg) -{ - if (narg < 4 || narg > 5) - error->all(FLERR,"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 epsilon_one = force->numeric(arg[2]); - double sigma_one = force->numeric(arg[3]); - - double cut_one = cut_global; - if (narg == 5) cut_one = force->numeric(arg[4]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - epsilon[i][j] = epsilon_one; - sigma[i][j] = sigma_one; - cut[i][j] = cut_one; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairTri::init_one(int i, int j) -{ - if (setflag[i][j] == 0) { - epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], - sigma[i][i],sigma[j][j]); - sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); - cut[i][j] = mix_distance(cut[i][i],cut[j][j]); - } - - lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); - lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); - lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); - lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); - - epsilon[j][i] = epsilon[i][j]; - sigma[j][i] = sigma[i][j]; - lj1[j][i] = lj1[i][j]; - lj2[j][i] = lj2[i][j]; - lj3[j][i] = lj3[i][j]; - lj4[j][i] = lj4[i][j]; - - return cut[i][j]; -} - -/* ---------------------------------------------------------------------- - recursively discretize triangle I with displaced corners c1,c2,c3 - into N sub-tris no more than sigma in size - recurse by making 2 tris via bisecting longest side - store new discrete particles in Discrete list -------------------------------------------------------------------------- */ - -void PairTri::discretize(int i, double sigma, - double *c1, double *c2, double *c3) -{ - double c1c2[3],c2c3[3],c1c3[3]; - - double centroid[3],dc1[3],dc2[3],dc3[3]; - - centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; - centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; - centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; - - MathExtra::sub3(c1,centroid,dc1); - MathExtra::sub3(c2,centroid,dc2); - MathExtra::sub3(c3,centroid,dc3); - - double sigmasq = 0.25 * sigma*sigma; - double len1sq = MathExtra::lensq3(dc1); - double len2sq = MathExtra::lensq3(dc2); - double len3sq = MathExtra::lensq3(dc3); - - // if sigma sphere overlaps all corner points, add particle at centroid - - if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { - if (ndiscrete == dmax) { - dmax += DELTA; - discrete = (Discrete *) - memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); - } - discrete[ndiscrete].dx = centroid[0]; - discrete[ndiscrete].dy = centroid[1]; - discrete[ndiscrete].dz = centroid[2]; - sigmasq = MAX(len1sq,len2sq); - sigmasq = MAX(sigmasq,len3sq); - discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); - ndiscrete++; - return; - } - - // else break triangle into 2 sub-triangles and recurse - - double c12[3],c23[3],c13[3],mid[3]; - - MathExtra::sub3(c2,c3,c23); - len1sq = MathExtra::lensq3(c23); - MathExtra::sub3(c1,c3,c13); - len2sq = MathExtra::lensq3(c13); - MathExtra::sub3(c1,c2,c12); - len3sq = MathExtra::lensq3(c12); - - double maxsq = MAX(len1sq,len2sq); - maxsq = MAX(maxsq,len3sq); - - if (len1sq == maxsq) { - MathExtra::add3(c2,c3,mid); - MathExtra::scale3(0.5,mid); - discretize(i,sigma,c1,c2,mid); - discretize(i,sigma,c1,c3,mid); - } else if (len2sq == maxsq) { - MathExtra::add3(c1,c3,mid); - MathExtra::scale3(0.5,mid); - discretize(i,sigma,c2,c1,mid); - discretize(i,sigma,c2,c3,mid); - } else { - MathExtra::add3(c1,c2,mid); - MathExtra::scale3(0.5,mid); - discretize(i,sigma,c3,c1,mid); - discretize(i,sigma,c3,c2,mid); - } -} - -/* ---------------------------------------------------------------------- - recursively discretize triangle I with displaced corners c1,c2,c3 - into N sub-tris no more than sigma in size - recurse by making 6 tris via centroid - store new discrete particles in Discrete list -------------------------------------------------------------------------- */ - -/* -void PairTri::discretize(int i, double sigma, - double *c1, double *c2, double *c3) -{ - double centroid[3],dc1[3],dc2[3],dc3[3]; - - centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; - centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; - centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; - - MathExtra::sub3(c1,centroid,dc1); - MathExtra::sub3(c2,centroid,dc2); - MathExtra::sub3(c3,centroid,dc3); - - double sigmasq = 0.25 * sigma*sigma; - double len1sq = MathExtra::lensq3(dc1); - double len2sq = MathExtra::lensq3(dc2); - double len3sq = MathExtra::lensq3(dc3); - - // if sigma sphere overlaps all corner points, add particle at centroid - - if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { - if (ndiscrete == dmax) { - dmax += DELTA; - discrete = (Discrete *) - memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); - } - discrete[ndiscrete].dx = centroid[0]; - discrete[ndiscrete].dy = centroid[1]; - discrete[ndiscrete].dz = centroid[2]; - sigmasq = MAX(len1sq,len2sq); - sigmasq = MAX(sigmasq,len3sq); - discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); - ndiscrete++; - return; - } - - // else break triangle into 6 sub-triangles and recurse - - double c1c2mid[3],c2c3mid[3],c1c3mid[3]; - - MathExtra::add3(c1,c2,c1c2mid); - MathExtra::scale3(0.5,c1c2mid); - MathExtra::add3(c2,c3,c2c3mid); - MathExtra::scale3(0.5,c2c3mid); - MathExtra::add3(c1,c3,c1c3mid); - MathExtra::scale3(0.5,c1c3mid); - - discretize(i,sigma,c1,c1c2mid,centroid); - discretize(i,sigma,c1,c1c3mid,centroid); - discretize(i,sigma,c2,c2c3mid,centroid); - discretize(i,sigma,c2,c1c2mid,centroid); - discretize(i,sigma,c3,c1c3mid,centroid); - discretize(i,sigma,c3,c2c3mid,centroid); -} - -*/ diff --git a/src/ASPHERE/pair_tri.h b/src/ASPHERE/pair_tri.h deleted file mode 100644 index fd1fe08bac..0000000000 --- a/src/ASPHERE/pair_tri.h +++ /dev/null @@ -1,61 +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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(tri,PairTri) - -#else - -#ifndef LMP_PAIR_TRI_H -#define LMP_PAIR_TRI_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairTri : public Pair { - public: - PairTri(class LAMMPS *); - ~PairTri(); - void compute(int, int); - void settings(int, char **); - void coeff(int, char **); - double init_one(int, int); - - protected: - double cut_global; - double **cut; - double **epsilon,**sigma; - double **lj1,**lj2,**lj3,**lj4; - class AtomVecTri *avec; - - struct Discrete { - double dx,dy,dz; - double sigma; - }; - Discrete *discrete; // list of all discretes for all lines - int ndiscrete; // number of discretes in list - int dmax; // allocated size of discrete list - int *dnum; // number of discretes per line, 0 if uninit - int *dfirst; // index of first discrete per each line - int nmax; // allocated size of dnum,dfirst vectors - - void allocate(); - void discretize(int, double, double *, double *, double *); -}; - -} - -#endif -#endif From 4322b98c8e6dc64cd801cf0b31eb5435f26471c8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:11:00 +0000 Subject: [PATCH 219/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7156 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/Install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index 1cc7a4b61d..77a640197c 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -14,7 +14,7 @@ if (test $1 = 1) then cp pair_gayberne.cpp .. cp pair_line_lj.cpp .. cp pair_resquared.cpp .. - cp pair_tri_Lj.cpp .. + cp pair_tri_lj.cpp .. cp compute_erotate_asphere.h .. cp compute_temp_asphere.h .. From ac909b6e18149919803f5c12c78291e49382102e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:13:28 +0000 Subject: [PATCH 220/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7157 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/pair_line_lj.cpp | 20 ++++++++++---------- src/ASPHERE/pair_line_lj.h | 12 ++++++------ src/ASPHERE/pair_tri_lj.cpp | 22 +++++++++++----------- src/ASPHERE/pair_tri_lj.h | 12 ++++++------ 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp index 4a3902c888..ca50168be5 100644 --- a/src/ASPHERE/pair_line_lj.cpp +++ b/src/ASPHERE/pair_line_lj.cpp @@ -15,7 +15,7 @@ #include "stdio.h" #include "stdlib.h" #include "string.h" -#include "pair_line.h" +#include "pair_line_lj.h" #include "atom.h" #include "atom_vec_line.h" #include "force.h" @@ -30,10 +30,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairLine::PairLine(LAMMPS *lmp) : Pair(lmp) +PairLineLJ::PairLineLJ(LAMMPS *lmp) : Pair(lmp) { avec = (AtomVecLine *) atom->style_match("line"); - if (!avec) error->all(FLERR,"Pair line requires atom style line"); + if (!avec) error->all(FLERR,"Pair line/lj requires atom style line"); dmax = nmax = 0; discrete = NULL; @@ -44,7 +44,7 @@ PairLine::PairLine(LAMMPS *lmp) : Pair(lmp) /* ---------------------------------------------------------------------- */ -PairLine::~PairLine() +PairLineLJ::~PairLineLJ() { memory->sfree(discrete); memory->destroy(dnum); @@ -66,7 +66,7 @@ PairLine::~PairLine() /* ---------------------------------------------------------------------- */ -void PairLine::compute(int eflag, int vflag) +void PairLineLJ::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; int ni,nj,npi,npj,ifirst,jfirst; @@ -307,7 +307,7 @@ void PairLine::compute(int eflag, int vflag) allocate all arrays ------------------------------------------------------------------------- */ -void PairLine::allocate() +void PairLineLJ::allocate() { allocated = 1; int n = atom->ntypes; @@ -332,7 +332,7 @@ void PairLine::allocate() global settings ------------------------------------------------------------------------- */ -void PairLine::settings(int narg, char **arg) +void PairLineLJ::settings(int narg, char **arg) { if (narg != 1) error->all(FLERR,"Illegal pair_style command"); @@ -352,7 +352,7 @@ void PairLine::settings(int narg, char **arg) set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairLine::coeff(int narg, char **arg) +void PairLineLJ::coeff(int narg, char **arg) { if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -386,7 +386,7 @@ void PairLine::coeff(int narg, char **arg) init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairLine::init_one(int i, int j) +double PairLineLJ::init_one(int i, int j) { if (setflag[i][j] == 0) { epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], @@ -415,7 +415,7 @@ double PairLine::init_one(int i, int j) store new discrete particles in Discrete list ------------------------------------------------------------------------- */ -void PairLine::discretize(int i, double sigma) +void PairLineLJ::discretize(int i, double sigma) { AtomVecLine::Bonus *bonus = avec->bonus; double length = bonus[atom->line[i]].length; diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h index 6598bfe6c1..b30140acea 100644 --- a/src/ASPHERE/pair_line_lj.h +++ b/src/ASPHERE/pair_line_lj.h @@ -13,21 +13,21 @@ #ifdef PAIR_CLASS -PairStyle(line,PairLine) +PairStyle(line/lj,PairLineLJ) #else -#ifndef LMP_PAIR_LINE_H -#define LMP_PAIR_LINE_H +#ifndef LMP_PAIR_LINE_LJ_H +#define LMP_PAIR_LINE_LJ_H #include "pair.h" namespace LAMMPS_NS { -class PairLine : public Pair { +class PairLineLJ : public Pair { public: - PairLine(class LAMMPS *); - ~PairLine(); + PairLineLJ(class LAMMPS *); + ~PairLineLJ(); void compute(int, int); void settings(int, char **); void coeff(int, char **); diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp index 0a40b8fb06..0ecf19aee5 100644 --- a/src/ASPHERE/pair_tri_lj.cpp +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -15,7 +15,7 @@ #include "stdio.h" #include "stdlib.h" #include "string.h" -#include "pair_tri.h" +#include "pair_tri_lj.h" #include "math_extra.h" #include "atom.h" #include "atom_vec_tri.h" @@ -31,10 +31,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairTri::PairTri(LAMMPS *lmp) : Pair(lmp) +PairTriLJ::PairTriLJ(LAMMPS *lmp) : Pair(lmp) { avec = (AtomVecTri *) atom->style_match("tri"); - if (!avec) error->all(FLERR,"Pair tri requires atom style tri"); + if (!avec) error->all(FLERR,"Pair tri/lj requires atom style tri"); dmax = nmax = 0; discrete = NULL; @@ -45,7 +45,7 @@ PairTri::PairTri(LAMMPS *lmp) : Pair(lmp) /* ---------------------------------------------------------------------- */ -PairTri::~PairTri() +PairTriLJ::~PairTriLJ() { memory->sfree(discrete); memory->destroy(dnum); @@ -67,7 +67,7 @@ PairTri::~PairTri() /* ---------------------------------------------------------------------- */ -void PairTri::compute(int eflag, int vflag) +void PairTriLJ::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; int ni,nj,npi,npj,ifirst,jfirst; @@ -391,7 +391,7 @@ void PairTri::compute(int eflag, int vflag) allocate all arrays ------------------------------------------------------------------------- */ -void PairTri::allocate() +void PairTriLJ::allocate() { allocated = 1; int n = atom->ntypes; @@ -416,7 +416,7 @@ void PairTri::allocate() global settings ------------------------------------------------------------------------- */ -void PairTri::settings(int narg, char **arg) +void PairTriLJ::settings(int narg, char **arg) { if (narg != 1) error->all(FLERR,"Illegal pair_style command"); @@ -436,7 +436,7 @@ void PairTri::settings(int narg, char **arg) set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairTri::coeff(int narg, char **arg) +void PairTriLJ::coeff(int narg, char **arg) { if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -470,7 +470,7 @@ void PairTri::coeff(int narg, char **arg) init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairTri::init_one(int i, int j) +double PairTriLJ::init_one(int i, int j) { if (setflag[i][j] == 0) { epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], @@ -501,7 +501,7 @@ double PairTri::init_one(int i, int j) store new discrete particles in Discrete list ------------------------------------------------------------------------- */ -void PairTri::discretize(int i, double sigma, +void PairTriLJ::discretize(int i, double sigma, double *c1, double *c2, double *c3) { double c1c2[3],c2c3[3],c1c3[3]; @@ -579,7 +579,7 @@ void PairTri::discretize(int i, double sigma, ------------------------------------------------------------------------- */ /* -void PairTri::discretize(int i, double sigma, +void PairTriLJ::discretize(int i, double sigma, double *c1, double *c2, double *c3) { double centroid[3],dc1[3],dc2[3],dc3[3]; diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h index fd1fe08bac..a8cf2bf721 100644 --- a/src/ASPHERE/pair_tri_lj.h +++ b/src/ASPHERE/pair_tri_lj.h @@ -13,21 +13,21 @@ #ifdef PAIR_CLASS -PairStyle(tri,PairTri) +PairStyle(tri/lj,PairTriLJ) #else -#ifndef LMP_PAIR_TRI_H -#define LMP_PAIR_TRI_H +#ifndef LMP_PAIR_TRI_LJ_H +#define LMP_PAIR_TRI_LJ_H #include "pair.h" namespace LAMMPS_NS { -class PairTri : public Pair { +class PairTriLJ : public Pair { public: - PairTri(class LAMMPS *); - ~PairTri(); + PairTriLJ(class LAMMPS *); + ~PairTriLJ(); void compute(int, int); void settings(int, char **); void coeff(int, char **); From 5667c71730bc33ecc051d2bd713faf49c013aeed Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:18:16 +0000 Subject: [PATCH 221/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7158 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_append_atoms.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp index 42fd494f96..9d59470f0d 100644 --- a/src/SHOCK/fix_append_atoms.cpp +++ b/src/SHOCK/fix_append_atoms.cpp @@ -64,38 +64,52 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Only zhi currently implemented for append_atoms"); xloflag = 1; iarg++; - if (domain->boundary[0][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum the append boundary"); + if (domain->boundary[0][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"xhi") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); xhiflag = 1; iarg++; - if (domain->boundary[0][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[0][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"ylo") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); yloflag = 1; iarg++; - if (domain->boundary[1][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"yhi") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); yhiflag = 1; iarg++; - if (domain->boundary[1][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"zlo") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); zloflag = 1; iarg++; - if (domain->boundary[2][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"zhi") == 0) { zhiflag = 1; iarg++; - if (domain->boundary[2][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"freq") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); freq = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"spatial") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal fix append_atoms command"); - if (strcmp(arg[iarg+1],"f_") == 0) error->all(FLERR,"Bad fix ID in fix append_atoms command"); + if (strcmp(arg[iarg+1],"f_") == 0) + error->all(FLERR, + "Bad fix ID in fix append_atoms command"); spatflag = 1; int n = strlen(arg[iarg+1]); spatlead = atof(arg[iarg+2]); @@ -106,7 +120,7 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : strcpy(spatialid,suffix); delete [] suffix; iarg += 3; - // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL + // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL } else if (strcmp(arg[iarg],"size") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); size = atof(arg[iarg+1]); @@ -152,7 +166,8 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : if ((zloflag || zhiflag) && domain->zperiodic) error->all(FLERR,"Cannot use append_atoms in periodic dimension"); - if (domain->triclinic == 1) error->all(FLERR,"Cannot append atoms to a triclinic box"); + if (domain->triclinic == 1) + error->all(FLERR,"Cannot append atoms to a triclinic box"); // setup scaling From 5cd9c6fe00012d8580000483f975a514eb7d3e00 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:37:44 +0000 Subject: [PATCH 222/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7160 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_intro.html | 3 ++- doc/Section_intro.txt | 3 ++- doc/pair_line_lj.html | 18 +++++++++--------- doc/pair_line_lj.txt | 18 +++++++++--------- doc/pair_tri_lj.html | 18 +++++++++--------- doc/pair_tri_lj.txt | 18 +++++++++--------- 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/doc/Section_intro.html b/doc/Section_intro.html index bced87e8c1..3b659cf8e7 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -125,7 +125,8 @@ LAMMPS.
      • metals
      • granular materials
      • coarse-grained mesoscale models -
      • extended spherical and ellipsoidal particles +
      • finite-size spherical and ellipsoidal particles +
      • finite-size line segment (2d) and triangle (3d) particles
      • point dipolar particles
      • rigid collections of particles
      • hybrid combinations of these diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 95a934830a..2ceb4f78d4 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -121,7 +121,8 @@ Particle and model types :h4 metals granular materials coarse-grained mesoscale models - extended spherical and ellipsoidal particles + finite-size spherical and ellipsoidal particles + finite-size line segment (2d) and triangle (3d) particles point dipolar particles rigid collections of particles hybrid combinations of these :ul diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html index 205c5f3f91..125bd41c5d 100644 --- a/doc/pair_line_lj.html +++ b/doc/pair_line_lj.html @@ -9,23 +9,23 @@
        -

        pair_style line command +

        pair_style line/lj command

        Syntax:

        -
        pair_style line cutoff 
        +
        pair_style line/lj cutoff 
         

        cutoff = global cutoff for interactions (distance units)

        Examples:

        -
        pair_style line 3.0
        +
        pair_style line/lj 3.0
         pair_coeff * * 1.0 1.0
         pair_coeff 1 1 1.0 1.5 2.5 
         

        Description:

        -

        Style line treats particles which are line segments as a set of +

        Style line/lj treats particles which are line segments as a set of small spherical particles that tile the line segment length as explained below. Interactions between two line segments, each with N1 and N2 spherical particles, are calculated as the pairwise sum of @@ -64,10 +64,10 @@ computed using only sigma_II values, specific to the line segment's type, this means that any specified sigma_IJ values (for I != J) are effectively ignored.

        -

        For style line, the following coefficients must be defined for each -pair of atoms types via the pair_coeff command as in -the examples above, or in the data file or restart files read by the -read_data or read_restart +

        For style line/lj, the following coefficients must be defined for +each pair of atoms types via the pair_coeff command +as in the examples above, or in the data file or restart files read by +the read_data or read_restart commands:

        • epsilon (energy units) @@ -110,7 +110,7 @@ line/line or line/particle interactions requires the use the

          Related commands:

          -

          pair_coeff +

          pair_coeff, pair_style tri/lj

          Default: none

          diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt index 160800250b..7f0bad0830 100644 --- a/doc/pair_line_lj.txt +++ b/doc/pair_line_lj.txt @@ -6,23 +6,23 @@ :line -pair_style line command :h3 +pair_style line/lj command :h3 [Syntax:] -pair_style line cutoff :pre +pair_style line/lj cutoff :pre cutoff = global cutoff for interactions (distance units) [Examples:] -pair_style line 3.0 +pair_style line/lj 3.0 pair_coeff * * 1.0 1.0 pair_coeff 1 1 1.0 1.5 2.5 :pre [Description:] -Style {line} treats particles which are line segments as a set of +Style {line/lj} treats particles which are line segments as a set of small spherical particles that tile the line segment length as explained below. Interactions between two line segments, each with N1 and N2 spherical particles, are calculated as the pairwise sum of @@ -61,10 +61,10 @@ computed using only sigma_II values, specific to the line segment's type, this means that any specified sigma_IJ values (for I != J) are effectively ignored. -For style {line}, the following coefficients must be defined for each -pair of atoms types via the "pair_coeff"_pair_coeff.html command as in -the examples above, or in the data file or restart files read by the -"read_data"_read_data.html or "read_restart"_read_restart.html +For style {line/lj}, the following coefficients must be defined for +each pair of atoms types via the "pair_coeff"_pair_coeff.html command +as in the examples above, or in the data file or restart files read by +the "read_data"_read_data.html or "read_restart"_read_restart.html commands: epsilon (energy units) @@ -107,6 +107,6 @@ line/line or line/particle interactions requires the use the [Related commands:] -"pair_coeff"_pair_coeff.html +"pair_coeff"_pair_coeff.html, "pair_style tri/lj"_pair_tri_lj.html [Default:] none diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html index 931819e107..76b4455fe7 100644 --- a/doc/pair_tri_lj.html +++ b/doc/pair_tri_lj.html @@ -9,23 +9,23 @@
          -

          pair_style tri command +

          pair_style tri/lj command

          Syntax:

          -
          pair_style tri cutoff 
          +
          pair_style tri/lj cutoff 
           

          cutoff = global cutoff for interactions (distance units)

          Examples:

          -
          pair_style tri 3.0
          +
          pair_style tri/lj 3.0
           pair_coeff * * 1.0 1.0
           pair_coeff 1 1 1.0 1.5 2.5 
           

          Description:

          -

          Style tri treats particles which are triangles as a set of small +

          Style tri/lj treats particles which are triangles as a set of small spherical particles that tile the triangle surface as explained below. Interactions between two triangles, each with N1 and N2 spherical particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones @@ -67,10 +67,10 @@ using only sigma_II values, specific to the triangles's type, this means that any specified sigma_IJ values (for I != J) are effectively ignored.

          -

          For style tri, the following coefficients must be defined for each -pair of atoms types via the pair_coeff command as in -the examples above, or in the data file or restart files read by the -read_data or read_restart +

          For style tri/lj, the following coefficients must be defined for +each pair of atoms types via the pair_coeff command +as in the examples above, or in the data file or restart files read by +the read_data or read_restart commands:

          • epsilon (energy units) @@ -113,7 +113,7 @@ tri command.

            Related commands:

            -

            pair_coeff +

            pair_coeff, pair_style line/lj

            Default: none

            diff --git a/doc/pair_tri_lj.txt b/doc/pair_tri_lj.txt index 47aea453e5..cfc64c52fd 100644 --- a/doc/pair_tri_lj.txt +++ b/doc/pair_tri_lj.txt @@ -6,23 +6,23 @@ :line -pair_style tri command :h3 +pair_style tri/lj command :h3 [Syntax:] -pair_style tri cutoff :pre +pair_style tri/lj cutoff :pre cutoff = global cutoff for interactions (distance units) [Examples:] -pair_style tri 3.0 +pair_style tri/lj 3.0 pair_coeff * * 1.0 1.0 pair_coeff 1 1 1.0 1.5 2.5 :pre [Description:] -Style {tri} treats particles which are triangles as a set of small +Style {tri/lj} treats particles which are triangles as a set of small spherical particles that tile the triangle surface as explained below. Interactions between two triangles, each with N1 and N2 spherical particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones @@ -64,10 +64,10 @@ using only sigma_II values, specific to the triangles's type, this means that any specified sigma_IJ values (for I != J) are effectively ignored. -For style {tri}, the following coefficients must be defined for each -pair of atoms types via the "pair_coeff"_pair_coeff.html command as in -the examples above, or in the data file or restart files read by the -"read_data"_read_data.html or "read_restart"_read_restart.html +For style {tri/lj}, the following coefficients must be defined for +each pair of atoms types via the "pair_coeff"_pair_coeff.html command +as in the examples above, or in the data file or restart files read by +the "read_data"_read_data.html or "read_restart"_read_restart.html commands: epsilon (energy units) @@ -110,6 +110,6 @@ tri"_atom_style.html command. [Related commands:] -"pair_coeff"_pair_coeff.html +"pair_coeff"_pair_coeff.html, "pair_style line/lj"_pair_line_lj.html [Default:] none From 30242a51bdc66e194717a1e4d31f76248e5f48af Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:41:59 +0000 Subject: [PATCH 223/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7161 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 5 +++-- doc/Section_commands.txt | 2 ++ doc/pair_sw.html | 2 ++ doc/pair_sw.txt | 1 + doc/pair_tersoff.html | 2 ++ doc/pair_tersoff.txt | 1 + 6 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 1781bf3b32..bebb8da72c 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -473,8 +473,9 @@ package. lj96/cut/cudalj96/cut/gpulj96/cut/omplubricate/omp morse/cudamorse/gpumorse/ompmorse/opt peri/lps/ompperi/pmb/omprebo/ompresquared/gpu resquared/omp -soft/ompsw/omptable/omptersoff/omp -tersoff/zbl/ompyukawa/ompyukawa/colloid/omp +soft/ompsw/cudasw/omptable/omp +tersoff/cudatersoff/omptersoff/zbl/ompyukawa/omp +yukawa/colloid/omp
            diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 67700fd323..713d0cfe4c 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -807,8 +807,10 @@ package"_Section_accelerate.html. "resquared/gpu"_pair_resquared.html "resquared/omp"_pair_resquared.html, "soft/omp"_pair_soft.html, +"sw/cuda"_pair_sw.html, "sw/omp"_pair_sw.html, "table/omp"_pair_table.html, +"tersoff/cuda"_pair_tersoff.html, "tersoff/omp"_pair_tersoff.html, "tersoff/zbl/omp"_pair_tersoff_zbl.html, "yukawa/omp"_pair_yukawa.html, diff --git a/doc/pair_sw.html b/doc/pair_sw.html index fe1fa3b116..6ea6f91277 100644 --- a/doc/pair_sw.html +++ b/doc/pair_sw.html @@ -11,6 +11,8 @@

            pair_style sw command

            +

            pair_style sw/cuda command +

            pair_style sw/omp command

            Syntax: diff --git a/doc/pair_sw.txt b/doc/pair_sw.txt index d1ea462f1b..6395470c8a 100644 --- a/doc/pair_sw.txt +++ b/doc/pair_sw.txt @@ -7,6 +7,7 @@ :line pair_style sw command :h3 +pair_style sw/cuda command :h3 pair_style sw/omp command :h3 [Syntax:] diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html index ecab9b3a4f..9686352730 100644 --- a/doc/pair_tersoff.html +++ b/doc/pair_tersoff.html @@ -15,6 +15,8 @@

            pair_style tersoff 
             
            +
            pair_style tersoff/cuda 
            +
            pair_style tersoff/omp 
             

            Examples: diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt index 7150c06b91..5d23f009f3 100644 --- a/doc/pair_tersoff.txt +++ b/doc/pair_tersoff.txt @@ -11,6 +11,7 @@ pair_style tersoff command :h3 [Syntax:] pair_style tersoff :pre +pair_style tersoff/cuda :pre pair_style tersoff/omp :pre [Examples:] From 8d409d8f2ee23451187adf371f5d7446fd1fd483 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:42:19 +0000 Subject: [PATCH 224/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7162 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/cuda_shared.h | 1 + lib/cuda/pair_manybody_const.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 lib/cuda/pair_manybody_const.h diff --git a/lib/cuda/cuda_shared.h b/lib/cuda/cuda_shared.h index 978a277712..a11c57dc22 100644 --- a/lib/cuda/cuda_shared.h +++ b/lib/cuda/cuda_shared.h @@ -81,6 +81,7 @@ struct cuda_shared_atom // relevent data from atom class int update_nlocal; int update_nmax; + int update_neigh; dev_array xhold; // position at last neighboring X_FLOAT triggerneighsq; // maximum square movement before reneighboring diff --git a/lib/cuda/pair_manybody_const.h b/lib/cuda/pair_manybody_const.h new file mode 100644 index 0000000000..69bf32aead --- /dev/null +++ b/lib/cuda/pair_manybody_const.h @@ -0,0 +1,16 @@ +/* + * pair_manybody_const.h + * + * Created on: Oct 11, 2011 + * Author: chmu-tph + */ + +#define MANYBODY_NPAIR 3 + +__device__ __constant__ int elem2param[(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)]; +__device__ __constant__ int nelements; +__device__ __constant__ int map[MANYBODY_NPAIR+2]; +__device__ __constant__ int* _glob_numneigh_red; //number of neighbors within force cutoff (as opposed to neighbor cutoff) +__device__ __constant__ int* _glob_neighbors_red; //indices of neighbors within force cutoff +__device__ __constant__ int* _glob_neightype_red; //type of neighbors within force cutoff + From fa80bceb30d0aadc2c6db58351aea0d77cd89e15 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 20 Oct 2011 15:44:25 +0000 Subject: [PATCH 225/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7163 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 78212f2ce3..522b480dc6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "19 Oct 2011" +#define LAMMPS_VERSION "20 Oct 2011" From cb5b707c7408cb26ac2336c86918ee151c289eca Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:45:39 +0000 Subject: [PATCH 226/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7177 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/Install.sh | 4 + src/ASPHERE/fix_nve_asphere.cpp | 2 +- src/ASPHERE/fix_nve_asphere_noforce.cpp | 109 +++++ src/ASPHERE/fix_nve_asphere_noforce.h | 41 ++ src/COLLOID/Install.sh | 4 - src/COLLOID/pair_lubricate.cpp | 523 ------------------------ src/COLLOID/pair_lubricate.h | 57 --- src/domain.h | 19 +- src/fix_nve_noforce.h | 6 +- src/fix_nve_sphere.cpp | 18 +- src/fix_nve_sphere.h | 1 - src/fix_wall.cpp | 25 +- src/fix_wall.h | 2 + 13 files changed, 196 insertions(+), 615 deletions(-) create mode 100644 src/ASPHERE/fix_nve_asphere_noforce.cpp create mode 100755 src/ASPHERE/fix_nve_asphere_noforce.h delete mode 100644 src/COLLOID/pair_lubricate.cpp delete mode 100644 src/COLLOID/pair_lubricate.h diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index 77a640197c..aca41e02b9 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -8,6 +8,7 @@ if (test $1 = 1) then cp fix_nph_asphere.cpp .. cp fix_npt_asphere.cpp .. cp fix_nve_asphere.cpp .. + cp fix_nve_asphere_noforce.cpp .. cp fix_nve_line.cpp .. cp fix_nve_tri.cpp .. cp fix_nvt_asphere.cpp .. @@ -22,6 +23,7 @@ if (test $1 = 1) then cp fix_nph_asphere.h .. cp fix_npt_asphere.h .. cp fix_nve_asphere.h .. + cp fix_nve_asphere_noforce.h .. cp fix_nve_line.h .. cp fix_nve_tri.h .. cp fix_nvt_asphere.h .. @@ -38,6 +40,7 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.cpp rm -f ../fix_npt_asphere.cpp rm -f ../fix_nve_asphere.cpp + rm -f ../fix_nve_asphere_noforce.cpp rm -f ../fix_nve_line.cpp rm -f ../fix_nve_tri.cpp rm -f ../fix_nvt_asphere.cpp @@ -52,6 +55,7 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.h rm -f ../fix_npt_asphere.h rm -f ../fix_nve_asphere.h + rm -f ../fix_nve_asphere_noforce.h rm -f ../fix_nve_line.h rm -f ../fix_nve_tri.h rm -f ../fix_nvt_asphere.h diff --git a/src/ASPHERE/fix_nve_asphere.cpp b/src/ASPHERE/fix_nve_asphere.cpp index 17ae8950e1..ac3abea6bc 100755 --- a/src/ASPHERE/fix_nve_asphere.cpp +++ b/src/ASPHERE/fix_nve_asphere.cpp @@ -45,7 +45,7 @@ FixNVEAsphere::FixNVEAsphere(LAMMPS *lmp, int narg, char **arg) : void FixNVEAsphere::init() { - // check that all particles are finite-size + // check that all particles are finite-size ellipsoids // no point particles allowed, spherical is OK int *ellipsoid = atom->ellipsoid; diff --git a/src/ASPHERE/fix_nve_asphere_noforce.cpp b/src/ASPHERE/fix_nve_asphere_noforce.cpp new file mode 100644 index 0000000000..42793723b5 --- /dev/null +++ b/src/ASPHERE/fix_nve_asphere_noforce.cpp @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + 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 "string.h" +#include "stdlib.h" +#include "fix_nve_asphere_noforce.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "group.h" +#include "update.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixNVEAsphereNoforce::FixNVEAsphereNoforce(LAMMPS *lmp, int narg, char **arg) : + FixNVENoforce(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Illegal fix nve/asphere/noforce command"); + + time_integrate = 1; + + // error check + + avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!atom->ellipsoid_flag) + error->all(FLERR,"Fix nve/asphere/noforce requires atom style ellipsoid"); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVEAsphereNoforce::init() +{ + FixNVENoforce::init(); + dtq = 0.5 * dtv; + + // check that all particles are finite-size ellipsoids + // no point particles allowed, spherical is OK + + int *ellipsoid = atom->ellipsoid; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + if (ellipsoid[i] < 0) + error->one(FLERR,"Fix nve/asphere/noforce requires extended particles"); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVEAsphereNoforce::initial_integrate(int vflag) +{ + AtomVecEllipsoid::Bonus *bonus; + if (avec) bonus = avec->bonus; + double **x = atom->x; + double **v = atom->v; + double **angmom = atom->angmom; + double *rmass = atom->rmass; + int *ellipsoid = atom->ellipsoid; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + double *shape,*quat; + double inertia[3],omega[3]; + + // update positions and quaternions for all particles + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + x[i][2] += dtv * v[i][2]; + + // principal moments of inertia + + shape = bonus[ellipsoid[i]].shape; + quat = bonus[ellipsoid[i]].quat; + + inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0; + inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0; + inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0; + + // compute omega at 1/2 step from angmom at 1/2 step and current q + // update quaternion a full step via Richardson iteration + // returns new normalized quaternion + + MathExtra::mq_to_omega(angmom[i],quat,inertia,omega); + MathExtra::richardson(quat,angmom[i],omega,inertia,dtq); + } + } +} diff --git a/src/ASPHERE/fix_nve_asphere_noforce.h b/src/ASPHERE/fix_nve_asphere_noforce.h new file mode 100755 index 0000000000..c1708ff7bb --- /dev/null +++ b/src/ASPHERE/fix_nve_asphere_noforce.h @@ -0,0 +1,41 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(nve/asphere/noforce,FixNVEAsphereNoforce) + +#else + +#ifndef LMP_FIX_NVE_ASPHERE_NOFORCE_H +#define LMP_FIX_NVE_ASPHERE_NOFORCE_H + +#include "fix_nve_noforce.h" + +namespace LAMMPS_NS { + +class FixNVEAsphereNoforce : public FixNVENoforce { + public: + FixNVEAsphereNoforce(class LAMMPS *, int, char **); + void initial_integrate(int); + void init(); + + private: + double dtq; + class AtomVecEllipsoid *avec; +}; + +} + +#endif +#endif diff --git a/src/COLLOID/Install.sh b/src/COLLOID/Install.sh index 4286a636f8..d5bac42feb 100644 --- a/src/COLLOID/Install.sh +++ b/src/COLLOID/Install.sh @@ -4,24 +4,20 @@ if (test $1 = 1) then cp fix_wall_colloid.cpp .. cp pair_colloid.cpp .. - cp pair_lubricate.cpp .. cp pair_yukawa_colloid.cpp .. cp fix_wall_colloid.h .. cp pair_colloid.h .. - cp pair_lubricate.h .. cp pair_yukawa_colloid.h .. elif (test $1 = 0) then rm -f ../fix_wall_colloid.cpp rm -f ../pair_colloid.cpp - rm -f ../pair_lubricate.cpp rm -f ../pair_yukawa_colloid.cpp rm -f ../fix_wall_colloid.h rm -f ../pair_colloid.h - rm -f ../pair_lubricate.h rm -f ../pair_yukawa_colloid.h fi diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp deleted file mode 100644 index f3c9a0dc06..0000000000 --- a/src/COLLOID/pair_lubricate.cpp +++ /dev/null @@ -1,523 +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. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Randy Schunk (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_lubricate.h" -#include "atom.h" -#include "atom_vec.h" -#include "comm.h" -#include "force.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "update.h" -#include "random_mars.h" -#include "math_const.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -/* ---------------------------------------------------------------------- */ - -PairLubricate::PairLubricate(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 0; - - random = NULL; -} - -/* ---------------------------------------------------------------------- */ - -PairLubricate::~PairLubricate() -{ - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(cut_inner); - } - - delete random; -} - -/* ---------------------------------------------------------------------- */ - -void PairLubricate::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz; - double rsq,r,h_sep,radi,tfmag; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3; - double vt1,vt2,vt3,w1,w2,w3,v_shear1,v_shear2,v_shear3; - double omega_t_1,omega_t_2,omega_t_3; - double n_cross_omega_t_1,n_cross_omega_t_2,n_cross_omega_t_3; - double wr1,wr2,wr3,wnnr,wn1,wn2,wn3; - double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3; - double a_squeeze,a_shear,a_pump,a_twist; - int *ilist,*jlist,*numneigh,**firstneigh; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - double **omega = atom->omega; - double **torque = atom->torque; - double *radius = atom->radius; - int *type = atom->type; - int nlocal = atom->nlocal; - int newton_pair = force->newton_pair; - double vxmu2f = force->vxmu2f; - - double prethermostat = sqrt(2.0 * force->boltz * t_target / update->dt); - prethermostat *= sqrt(force->vxmu2f/force->ftm2v/force->mvv2e); - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // loop over neighbors of my atoms - - a_squeeze = a_shear = a_pump = a_twist = 0.0; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itype = type[i]; - radi = radius[i]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - - 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]) { - - r = sqrt(rsq); - - // relative translational velocity - - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component N.(v1-v2) = nn.(v1-v2) - - vnnr = vr1*delx + vr2*dely + vr3*delz; - vnnr /= r; - vn1 = delx*vnnr / r; - vn2 = dely*vnnr / r; - vn3 = delz*vnnr / r; - - // tangential component -P.(v1-v2) - // P = (I - nn) where n is vector between centers - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // additive rotational velocity = omega_1 + omega_2 - - w1 = omega[i][0] + omega[j][0]; - w2 = omega[i][1] + omega[j][1]; - w3 = omega[i][2] + omega[j][2]; - - // relative velocities n X P . (v1-v2) = n X (I-nn) . (v1-v2) - - v_shear1 = (dely*vt3 - delz*vt2) / r; - v_shear2 = -(delx*vt3 - delz*vt1) / r; - v_shear3 = (delx*vt2 - dely*vt1) / r; - - // relative rotation rate P.(omega1 + omega2) - - omega_t_1 = w1 - delx*(delx*w1) / rsq; - omega_t_2 = w2 - dely*(dely*w2) / rsq; - omega_t_3 = w3 - delz*(delz*w3) / rsq; - - // n X omega_t - - n_cross_omega_t_1 = (dely*omega_t_3 - delz*omega_t_2) / r; - n_cross_omega_t_2 = -(delx*omega_t_3 - delz*omega_t_1) / r; - n_cross_omega_t_3 = (delx*omega_t_2 - dely*omega_t_1) / r; - - // N.(w1-w2) and P.(w1-w2) - - wr1 = omega[i][0] - omega[j][0]; - wr2 = omega[i][1] - omega[j][1]; - wr3 = omega[i][2] - omega[j][2]; - - wnnr = wr1*delx + wr2*dely + wr3*delz; - wn1 = delx*wnnr / rsq; - wn2 = dely*wnnr / rsq; - wn3 = delz*wnnr / rsq; - - P_dot_wrel_1 = wr1 - delx*(delx*wr1)/rsq; - P_dot_wrel_2 = wr2 - dely*(dely*wr2)/rsq; - P_dot_wrel_3 = wr3 - delz*(delz*wr3)/rsq; - - // compute components of pair-hydro - - h_sep = r - 2.0*radi; - - if (flag1) - a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); - if (flag2) - a_shear = (MY_PI*mu*2.*radi/2.0) * - log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0; - if (flag3) - a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) * - ((3.0/20.0) * log(2.0*radi/2.0/h_sep) + - (63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep)); - if (flag4) - a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) * - (h_sep/2.0/radi) * log(2.0/(2.0*h_sep)); - - if (h_sep >= cut_inner[itype][jtype]) { - fx = -a_squeeze*vn1 - a_shear*(2.0/r)*(2.0/r)*vt1 + - (2.0/r)*a_shear*n_cross_omega_t_1; - fy = -a_squeeze*vn2 - a_shear*(2.0/r)*(2.0/r)*vt2 + - (2.0/r)*a_shear*n_cross_omega_t_2; - fz = -a_squeeze*vn3 - a_shear*(2.0/r)*(2.0/r)*vt3 + - (2.0/r)*a_shear*n_cross_omega_t_3; - fx *= vxmu2f; - fy *= vxmu2f; - fz *= vxmu2f; - - // add in thermostat force - - tfmag = prethermostat*sqrt(a_squeeze)*(random->uniform()-0.5); - fx -= tfmag * delx/r; - fy -= tfmag * dely/r; - fz -= tfmag * delz/r; - - tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 - - a_pump*P_dot_wrel_1 - a_twist*wn1; - ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 - - a_pump*P_dot_wrel_2 - a_twist*wn2; - tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 - - a_pump*P_dot_wrel_3 - a_twist*wn3; - torque[i][0] += vxmu2f * tx; - torque[i][1] += vxmu2f * ty; - torque[i][2] += vxmu2f * tz; - - } else { - a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * - (2.0*radi/4.0/cut_inner[itype][jtype]); - fpair = -a_squeeze*vnnr; - fpair *= vxmu2f; - - // add in thermostat force - - fpair -= prethermostat*sqrt(a_squeeze)*(random->uniform()-0.5); - - fx = fpair * delx/r; - fy = fpair * dely/r; - fz = fpair * delz/r; - } - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - if (newton_pair || j < nlocal) { - f[j][0] -= fx; - f[j][1] -= fy; - f[j][2] -= fz; - - if (h_sep >= cut_inner[itype][jtype]) { - tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 + - a_pump*P_dot_wrel_1 + a_twist*wn1; - ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 + - a_pump*P_dot_wrel_2 + a_twist*wn2; - tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 + - a_pump*P_dot_wrel_3 + a_twist*wn3; - torque[j][0] += vxmu2f * tx; - torque[j][1] += vxmu2f * ty; - torque[j][2] += vxmu2f * tz; - } - } - - if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairLubricate::allocate() -{ - allocated = 1; - int n = atom->ntypes; - - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; - - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(cut_inner,n+1,n+1,"pair:cut_inner"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairLubricate::settings(int narg, char **arg) -{ - if (narg != 9) error->all(FLERR,"Illegal pair_style command"); - - mu = force->numeric(arg[0]); - flag1 = force->inumeric(arg[1]); - flag2 = force->inumeric(arg[2]); - flag3 = force->inumeric(arg[3]); - flag4 = force->inumeric(arg[4]); - cut_inner_global = force->numeric(arg[5]); - cut_global = force->numeric(arg[6]); - t_target = force->numeric(arg[7]); - seed = force->inumeric(arg[8]); - - // initialize Marsaglia RNG with processor-unique seed - - if (seed <= 0) error->all(FLERR,"Illegal pair_style command"); - delete random; - random = new RanMars(lmp,seed + comm->me); - - // 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_inner[i][j] = cut_inner_global; - cut[i][j] = cut_global; - } - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairLubricate::coeff(int narg, char **arg) -{ - if (narg != 2 && narg != 4) - error->all(FLERR,"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_inner_one = cut_inner_global; - double cut_one = cut_global; - if (narg == 4) { - cut_inner_one = force->numeric(arg[2]); - cut_one = force->numeric(arg[3]); - } - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - cut_inner[i][j] = cut_inner_one; - cut[i][j] = cut_one; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLubricate::init_style() -{ - if (!atom->sphere_flag) - error->all(FLERR,"Pair lubricate requires atom style sphere"); - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair lubricate requires ghost atoms store velocity"); - - neighbor->request(this); - - // require that atom radii are identical within each type - // require monodisperse system with same radii for all types - - double rad,radtype; - for (int i = 1; i <= atom->ntypes; i++) { - if (!atom->radius_consistency(i,radtype)) - error->all(FLERR,"Pair lubricate requires monodisperse particles"); - if (i > 1 && radtype != rad) - error->all(FLERR,"Pair lubricate requires monodisperse particles"); - rad = radtype; - } -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairLubricate::init_one(int i, int j) -{ - if (setflag[i][j] == 0) { - cut_inner[i][j] = mix_distance(cut_inner[i][i],cut_inner[j][j]); - cut[i][j] = mix_distance(cut[i][i],cut[j][j]); - } - - cut_inner[j][i] = cut_inner[i][j]; - - return cut[i][j]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLubricate::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_inner[i][j],sizeof(double),1,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairLubricate::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_inner[i][j],sizeof(double),1,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&cut_inner[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLubricate::write_restart_settings(FILE *fp) -{ - fwrite(&mu,sizeof(double),1,fp); - fwrite(&flag1,sizeof(int),1,fp); - fwrite(&flag2,sizeof(int),1,fp); - fwrite(&flag3,sizeof(int),1,fp); - fwrite(&flag4,sizeof(int),1,fp); - fwrite(&cut_inner_global,sizeof(double),1,fp); - fwrite(&cut_global,sizeof(double),1,fp); - fwrite(&t_target,sizeof(double),1,fp); - fwrite(&seed,sizeof(int),1,fp); - fwrite(&offset_flag,sizeof(int),1,fp); - fwrite(&mix_flag,sizeof(int),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairLubricate::read_restart_settings(FILE *fp) -{ - int me = comm->me; - if (me == 0) { - fread(&mu,sizeof(double),1,fp); - fread(&flag1,sizeof(int),1,fp); - fread(&flag2,sizeof(int),1,fp); - fread(&flag3,sizeof(int),1,fp); - fread(&flag4,sizeof(int),1,fp); - fread(&cut_inner_global,sizeof(double),1,fp); - fread(&cut_global,sizeof(double),1,fp); - fread(&t_target, sizeof(double),1,fp); - fread(&seed, sizeof(int),1,fp); - fread(&offset_flag,sizeof(int),1,fp); - fread(&mix_flag,sizeof(int),1,fp); - } - MPI_Bcast(&mu,1,MPI_DOUBLE,0,world); - MPI_Bcast(&flag1,1,MPI_INT,0,world); - MPI_Bcast(&flag2,1,MPI_INT,0,world); - MPI_Bcast(&flag3,1,MPI_INT,0,world); - MPI_Bcast(&flag4,1,MPI_INT,0,world); - MPI_Bcast(&cut_inner_global,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); - MPI_Bcast(&t_target,1,MPI_DOUBLE,0,world); - MPI_Bcast(&seed,1,MPI_INT,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); - - // additional setup based on restart parameters - - delete random; - random = new RanMars(lmp,seed + comm->me); -} - -/* ---------------------------------------------------------------------- */ - -void *PairLubricate::extract(char *str, int &dim) -{ - dim = 0; - if (strcmp(str,"mu") == 0) return (void *) μ - return NULL; -} diff --git a/src/COLLOID/pair_lubricate.h b/src/COLLOID/pair_lubricate.h deleted file mode 100644 index 30c9f71baf..0000000000 --- a/src/COLLOID/pair_lubricate.h +++ /dev/null @@ -1,57 +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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(lubricate,PairLubricate) - -#else - -#ifndef LMP_PAIR_LUBRICATE_H -#define LMP_PAIR_LUBRICATE_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairLubricate : public Pair { - public: - PairLubricate(class LAMMPS *); - virtual ~PairLubricate(); - virtual void compute(int, int); - void settings(int, char **); - void coeff(int, char **); - double init_one(int, int); - void init_style(); - void write_restart(FILE *); - void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - void *extract(char *, int &); - - protected: - double cut_inner_global,cut_global; - double t_target,mu; - int flag1,flag2,flag3,flag4; - int seed; - double **cut_inner,**cut; - - class RanMars *random; - - void allocate(); -}; - -} - -#endif -#endif diff --git a/src/domain.h b/src/domain.h index a6fee60963..c07808ca02 100644 --- a/src/domain.h +++ b/src/domain.h @@ -93,15 +93,16 @@ class Domain : protected Pointers { virtual void set_local_box(); virtual void reset_box(); virtual void pbc(); - void remap(double *, int &); - void remap(double *); - void remap_near(double *, double *); - void unmap(double *, int); - void unmap(double *, int, double *); - int minimum_image_check(double, double, double); - void minimum_image(double &, double &, double &); - void minimum_image(double *); - void closest_image(double *, double *, double *); + virtual void remap(double *, int &); + virtual void remap(double *); + virtual void remap_near(double *, double *); + virtual void unmap(double *, int); + virtual void unmap(double *, int, double *); + virtual int minimum_image_check(double, double, double); + virtual void minimum_image(double &, double &, double &); + virtual void minimum_image(double *); + virtual void closest_image(double *, double *, double *); + void set_lattice(int, char **); void add_region(int, char **); void delete_region(int, char **); diff --git a/src/fix_nve_noforce.h b/src/fix_nve_noforce.h index d56ecd96a1..90989869b8 100644 --- a/src/fix_nve_noforce.h +++ b/src/fix_nve_noforce.h @@ -28,12 +28,12 @@ class FixNVENoforce : public Fix { public: FixNVENoforce(class LAMMPS *, int, char **); int setmask(); - void init(); - void initial_integrate(int); + virtual void init(); + virtual void initial_integrate(int); void initial_integrate_respa(int, int, int); void reset_dt(); - private: + protected: double dtv; double *step_respa; }; diff --git a/src/fix_nve_sphere.cpp b/src/fix_nve_sphere.cpp index c81452994c..a00fa0bdf1 100644 --- a/src/fix_nve_sphere.cpp +++ b/src/fix_nve_sphere.cpp @@ -61,21 +61,11 @@ FixNVESphere::FixNVESphere(LAMMPS *lmp, int narg, char **arg) : /* ---------------------------------------------------------------------- */ -int FixNVESphere::setmask() -{ - int mask = 0; - mask |= INITIAL_INTEGRATE; - mask |= FINAL_INTEGRATE; - mask |= INITIAL_INTEGRATE_RESPA; - mask |= FINAL_INTEGRATE_RESPA; - return mask; -} - -/* ---------------------------------------------------------------------- */ - void FixNVESphere::init() { - // check that all particles are finite-size + FixNVE::init(); + + // check that all particles are finite-size spheres // no point particles allowed double *radius = atom->radius; @@ -86,8 +76,6 @@ void FixNVESphere::init() if (mask[i] & groupbit) if (radius[i] == 0.0) error->one(FLERR,"Fix nve/sphere requires extended particles"); - - FixNVE::init(); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_nve_sphere.h b/src/fix_nve_sphere.h index 28fc47c591..c3148c2c54 100644 --- a/src/fix_nve_sphere.h +++ b/src/fix_nve_sphere.h @@ -28,7 +28,6 @@ class FixNVESphere : public FixNVE { public: FixNVESphere(class LAMMPS *, int, char **); virtual ~FixNVESphere() {} - int setmask(); void init(); virtual void initial_integrate(int); virtual void final_integrate(); diff --git a/src/fix_wall.cpp b/src/fix_wall.cpp index 3cc68017cc..2be0651690 100644 --- a/src/fix_wall.cpp +++ b/src/fix_wall.cpp @@ -45,6 +45,7 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : nwall = 0; int scaleflag = 1; + fldflag = 0; int iarg = 3; while (iarg < narg) { @@ -94,6 +95,12 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; else error->all(FLERR,"Illegal fix wall command"); iarg += 2; + } else if (strcmp(arg[iarg],"fld") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall command"); + if (strcmp(arg[iarg+1],"no") == 0) fldflag = 0; + else if (strcmp(arg[iarg+1],"yes") == 0) fldflag = 1; + else error->all(FLERR,"Illegal fix wall command"); + iarg += 2; } else error->all(FLERR,"Illegal fix wall command"); } @@ -169,7 +176,12 @@ FixWall::~FixWall() int FixWall::setmask() { int mask = 0; - mask |= POST_FORCE; + + // FLD implicit needs to invoke wall forces before pair style + + if (fldflag) mask != PRE_FORCE; + else mask |= POST_FORCE; + mask |= THERMO_ENERGY; mask |= POST_FORCE_RESPA; mask |= MIN_POST_FORCE; @@ -204,7 +216,7 @@ void FixWall::init() void FixWall::setup(int vflag) { if (strstr(update->integrate_style,"verlet")) - post_force(vflag); + if (!fldflag) post_force(vflag); else { ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1); post_force_respa(vflag,nlevels_respa-1,0); @@ -219,6 +231,15 @@ void FixWall::min_setup(int vflag) post_force(vflag); } +/* ---------------------------------------------------------------------- + only called if fldflag set, in place of post_force +------------------------------------------------------------------------- */ + +void FixWall::pre_force(int vflag) +{ + post_force(vflag); +} + /* ---------------------------------------------------------------------- */ void FixWall::post_force(int vflag) diff --git a/src/fix_wall.h b/src/fix_wall.h index 8c0c39d024..62ee69bc54 100644 --- a/src/fix_wall.h +++ b/src/fix_wall.h @@ -26,6 +26,7 @@ class FixWall : public Fix { virtual void init(); void setup(int); void min_setup(int); + void pre_force(int); void post_force(int); void post_force_respa(int, int, int); void min_post_force(int); @@ -45,6 +46,7 @@ class FixWall : public Fix { double ewall[7],ewall_all[7]; int nlevels_respa; double dt; + int fldflag; }; } From 326c40feaa41390fa3b7b120890d016dd8800dac Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:46:47 +0000 Subject: [PATCH 227/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7178 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 43 ++++---- doc/Section_commands.txt | 6 ++ doc/fix.html | 7 +- doc/fix.txt | 7 +- doc/fix_nve_asphere_noforce.html | 70 ++++++++++++ doc/fix_nve_asphere_noforce.txt | 65 +++++++++++ doc/fix_wall.html | 14 ++- doc/fix_wall.txt | 14 ++- doc/fix_wall_reflect.txt | 8 +- doc/pair_coeff.html | 5 + doc/pair_coeff.txt | 5 + doc/pair_lubricate.html | 178 ------------------------------- doc/pair_lubricate.txt | 171 ----------------------------- doc/pair_style.html | 5 + doc/pair_style.txt | 5 + 15 files changed, 219 insertions(+), 384 deletions(-) create mode 100644 doc/fix_nve_asphere_noforce.html create mode 100755 doc/fix_nve_asphere_noforce.txt delete mode 100644 doc/pair_lubricate.html delete mode 100644 doc/pair_lubricate.txt diff --git a/doc/Section_commands.html b/doc/Section_commands.html index bebb8da72c..c69566e177 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -341,12 +341,12 @@ of each style or click on the style itself for a full description: efieldenforce2devaporateexternalfreezegcmcgravityheat indentlangevinlineforcemomentummovemsstnebnph nphugnph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/asphere -nve/limitnve/linenve/noforcenve/spherenve/trinvtnvt/aspherenvt/sllod -nvt/sphereorient/fccplaneforcepoemspourpress/berendsenprintqeq/comb -reax/bondsrecenterrestrainrigidrigid/nverigid/nvtsetforceshake -springspring/rgspring/selfsrdstore/forcestore/statetemp/berendsentemp/rescale -thermal/conductivitytmdttmviscosityviscouswall/colloidwall/granwall/harmonic -wall/lj126wall/lj93wall/reflectwall/regionwall/srd +nve/asphere/noforcenve/limitnve/linenve/noforcenve/spherenve/trinvtnvt/asphere +nvt/sllodnvt/sphereorient/fccplaneforcepoemspourpress/berendsenprint +qeq/combreax/bondsrecenterrestrainrigidrigid/nverigid/nvtsetforce +shakespringspring/rgspring/selfsrdstore/forcestore/statetemp/berendsen +temp/rescalethermal/conductivitytmdttmviscosityviscouswall/colloidwall/gran +wall/harmonicwall/lj126wall/lj93wall/reflectwall/regionwall/srd

            These are fix styles contributed by users, which can be used if @@ -413,21 +413,22 @@ potentials. Click on the style itself for a full description:

            - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
            nonehybridhybrid/overlayadp
            airebobornborn/coul/longbuck
            buck/coul/cutbuck/coul/longcolloidcomb
            coul/cutcoul/debyecoul/longdipole/cut
            dpddpd/tstatdsmceam
            eam/alloyeam/fseimgauss
            gaybernegran/hertz/historygran/hookegran/hooke/history
            hbond/dreiding/ljhbond/dreiding/morseline/ljlj/charmm/coul/charmm
            lj/charmm/coul/charmm/implicitlj/charmm/coul/longlj/class2lj/class2/coul/cut
            lj/class2/coul/longlj/cutlj/cut/coul/cutlj/cut/coul/debye
            lj/cut/coul/longlj/cut/coul/long/tip4plj/expandlj/gromacs
            lj/gromacs/coul/gromacslj/smoothlj96/cutlubricate
            meammorseperi/lpsperi/pmb
            reaxreboresquaredsoft
            swtabletersofftersoff/zbl
            tri/ljyukawayukawa/colloid +
            airebobornborn/coul/longbrownian
            brownian/polybuckbuck/coul/cutbuck/coul/long
            colloidcombcoul/cutcoul/debye
            coul/longdipole/cutdpddpd/tstat
            dsmceameam/alloyeam/fs
            eimgaussgaybernegran/hertz/history
            gran/hookegran/hooke/historyhbond/dreiding/ljhbond/dreiding/morse
            line/ljlj/charmm/coul/charmmlj/charmm/coul/charmm/implicitlj/charmm/coul/long
            lj/class2lj/class2/coul/cutlj/class2/coul/longlj/cut
            lj/cut/coul/cutlj/cut/coul/debyelj/cut/coul/longlj/cut/coul/long/tip4p
            lj/expandlj/gromacslj/gromacs/coul/gromacslj/smooth
            lj96/cutlubricatelubricate/polylubricateU
            lubricateU/polymeammorseperi/lps
            peri/pmbreaxreboresquared
            softswtabletersoff
            tersoff/zbltri/ljyukawayukawa/colloid

            These are pair styles contributed by users, which can be used if diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 713d0cfe4c..e8ca9cf708 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -437,6 +437,7 @@ of each style or click on the style itself for a full description: "npt/sphere"_fix_npt_sphere.html, "nve"_fix_nve.html, "nve/asphere"_fix_nve_asphere.html, +"nve/asphere/noforce"_fix_nve_asphere_noforce.html, "nve/limit"_fix_nve_limit.html, "nve/line"_fix_nve_line.html, "nve/noforce"_fix_nve_noforce.html, @@ -617,6 +618,8 @@ potentials. Click on the style itself for a full description: "airebo"_pair_airebo.html, "born"_pair_born.html, "born/coul/long"_pair_born.html, +"brownian"_pair_brownian.html, +"brownian/poly"_pair_brownian.html, "buck"_pair_buck.html, "buck/coul/cut"_pair_buck.html, "buck/coul/long"_pair_buck.html, @@ -658,6 +661,9 @@ potentials. Click on the style itself for a full description: "lj/smooth"_pair_lj_smooth.html, "lj96/cut"_pair_lj96.html, "lubricate"_pair_lubricate.html, +"lubricate/poly"_pair_lubricate.html, +"lubricateU"_pair_lubricateU.html, +"lubricateU/poly"_pair_lubricateU.html, "meam"_pair_meam.html, "morse"_pair_morse.html, "peri/lps"_pair_peri.html, diff --git a/doc/fix.html b/doc/fix.html index 6d84638722..b2cac319d7 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -198,11 +198,12 @@ list of fix styles available in LAMMPS:

          • npt/asphere - NPT for aspherical particles
          • npt/sphere - NPT for spherical particles
          • nve - constant NVE time integration -
          • nve/asphere - NVT for aspherical particles -
          • nve/limit - NVE with limited step length +
          • nve/asphere - NVE for aspherical particles +
          • nve/asphere/noforce - NVE for aspherical particles without forces +
          • nve/limit - NVE with limited step length
          • nve/line - NVE for line segments
          • nve/noforce - NVE without forces (v only) -
          • nve/sphere - NVT for spherical particles +
          • nve/sphere - NVE for spherical particles
          • nve/tri - NVE for triangles
          • nvt - constant NVT time integration via Nose/Hoover
          • nvt/asphere - NVT for aspherical particles diff --git a/doc/fix.txt b/doc/fix.txt index 6b824cf10c..4c0df45d11 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -193,11 +193,12 @@ list of fix styles available in LAMMPS: "npt/asphere"_fix_npt_asphere.html - NPT for aspherical particles "npt/sphere"_fix_npt_sphere.html - NPT for spherical particles "nve"_fix_nve.html - constant NVE time integration -"nve/asphere"_fix_nve_asphere.html - NVT for aspherical particles -"nve/limit"_fix_nve_limit.html - NVE with limited step length +"nve/asphere"_fix_nve_asphere.html - NVE for aspherical particles +"nve/asphere/noforce"_fix_nve_asphere_noforce.html - NVE for aspherical particles without forces" +nve/limit"_fix_nve_limit.html - NVE with limited step length "nve/line"_fix_nve_line.html - NVE for line segments "nve/noforce"_fix_nve_noforce.html - NVE without forces (v only) -"nve/sphere"_fix_nve_sphere.html - NVT for spherical particles +"nve/sphere"_fix_nve_sphere.html - NVE for spherical particles "nve/tri"_fix_nve_tri.html - NVE for triangles "nvt"_fix_nh.html - constant NVT time integration via Nose/Hoover "nvt/asphere"_fix_nvt_asphere.html - NVT for aspherical particles diff --git a/doc/fix_nve_asphere_noforce.html b/doc/fix_nve_asphere_noforce.html new file mode 100644 index 0000000000..4dd6f31ad6 --- /dev/null +++ b/doc/fix_nve_asphere_noforce.html @@ -0,0 +1,70 @@ + +
            LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
            + + + + + + +
            + +

            fix nve/asphere/noforce command +

            +

            Syntax: +

            +
            fix ID group-ID nve/asphere/noforce 
            +
            +
            • ID, group-ID are documented in fix command +
            • nve/asphere/noforce = style name of this fix command +
            +

            Examples: +

            +

            fix 1 all nve/asphere/noforce +

            +

            Description: +

            +

            Perform updates of position and orientation, but not velocity or +angular momentum for atoms in the group each timestep. In other +words, the force and torque on the atoms is ignored and their velocity +and angular momentum are not updated. The atom velocities and +angularm momenta are used to update their positions and orientation. +

            +

            This is useful as an implicit time integrator for Fast Lubrication +Dynamics, since the velocity and angular momentum are updated by the +pair_style lubricuteU command. +

            +
            + +

            Restart, fix_modify, output, run start/stop, minimize info: +

            +

            No information about this fix is written to binary restart +files. None of the fix_modify options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various output +commands. No parameter of this fix can +be used with the start/stop keywords of the run command. +This fix is not invoked during energy minimization. +

            +

            Restrictions: +

            +

            This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

            +

            This fix requires that atoms store torque and angular momementum and a +quaternion as defined by the atom_style ellipsoid +command. +

            +

            All particles in the group must be finite-size. They cannot be point +particles, but they can be aspherical or spherical as defined by their +shape attribute. +

            +

            Related commands: +

            +

            fix nve/noforce, fix +nve/asphere +

            +

            Default: none +

            + diff --git a/doc/fix_nve_asphere_noforce.txt b/doc/fix_nve_asphere_noforce.txt new file mode 100755 index 0000000000..bc7bc698d2 --- /dev/null +++ b/doc/fix_nve_asphere_noforce.txt @@ -0,0 +1,65 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix nve/asphere/noforce command :h3 + +[Syntax:] + +fix ID group-ID nve/asphere/noforce :pre + +ID, group-ID are documented in "fix"_fix.html command +nve/asphere/noforce = style name of this fix command :ul + +[Examples:] + +fix 1 all nve/asphere/noforce + +[Description:] + +Perform updates of position and orientation, but not velocity or +angular momentum for atoms in the group each timestep. In other +words, the force and torque on the atoms is ignored and their velocity +and angular momentum are not updated. The atom velocities and +angularm momenta are used to update their positions and orientation. + +This is useful as an implicit time integrator for Fast Lubrication +Dynamics, since the velocity and angular momentum are updated by the +"pair_style lubricuteU"_pair_lubricateU.txt command. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. None of the "fix_modify"_fix_modify.html options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various "output +commands"_Section_howto.html#howto_15. No parameter of this fix can +be used with the {start/stop} keywords of the "run"_run.html command. +This fix is not invoked during "energy minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +This fix requires that atoms store torque and angular momementum and a +quaternion as defined by the "atom_style ellipsoid"_atom_style.html +command. + +All particles in the group must be finite-size. They cannot be point +particles, but they can be aspherical or spherical as defined by their +shape attribute. + +[Related commands:] + +"fix nve/noforce"_fix_nve_noforce.html, "fix +nve/asphere"_fix_nve_asphere.html + +[Default:] none diff --git a/doc/fix_wall.html b/doc/fix_wall.html index 8bc4f23aa2..b4612a7f31 100644 --- a/doc/fix_wall.html +++ b/doc/fix_wall.html @@ -40,11 +40,14 @@
        • zero or more keyword/value pairs may be appended -
        • keyword = units +
        • keyword = units or fld
            units value = lattice or box
               lattice = the wall position is defined in lattice units
          -    box = the wall position is defined in simulation box units 
          +    box = the wall position is defined in simulation box units
          +  fld value = yes or no
          +    yes = invoke the wall constraint to be compatible with implicit FLD
          +    yes = invoke the wall constraint in the normal way 
           
        @@ -162,6 +165,13 @@ A lattice value means the distance units are in lattice spacings. The lattice command must have been previously used to define the lattice spacings.

        +

        The fld keyword can be used with a yes setting to invoke the wall +constraint before pairwise interactions are computed. This allows an +implicit FLD model using pair_style lubricateU +to include the wall force in its calculations. If the setting is +no, wall forces are imposed after pairwise interactions, in the +usual manner. +


        Here are examples of variable definitions that move the wall position diff --git a/doc/fix_wall.txt b/doc/fix_wall.txt index a3614c2433..14bab6db03 100644 --- a/doc/fix_wall.txt +++ b/doc/fix_wall.txt @@ -28,10 +28,13 @@ face = {xlo} or {xhi} or {ylo} or {yhi} or {zlo} or {zhi} :l sigma = size factor for wall-particle interaction (distance units) cutoff = distance from wall at which wall-particle interaction is cut off (distance units) :pre zero or more keyword/value pairs may be appended :l -keyword = {units} :l +keyword = {units} or {fld} :l {units} value = {lattice} or {box} {lattice} = the wall position is defined in lattice units - {box} = the wall position is defined in simulation box units :pre + {box} = the wall position is defined in simulation box units + {fld} value = {yes} or {no} + {yes} = invoke the wall constraint to be compatible with implicit FLD + {yes} = invoke the wall constraint in the normal way :pre :ule [Examples:] @@ -148,6 +151,13 @@ A {lattice} value means the distance units are in lattice spacings. The "lattice"_lattice.html command must have been previously used to define the lattice spacings. +The {fld} keyword can be used with a {yes} setting to invoke the wall +constraint before pairwise interactions are computed. This allows an +implicit FLD model using "pair_style lubricateU"_pair_lubricateU.html +to include the wall force in its calculations. If the setting is +{no}, wall forces are imposed after pairwise interactions, in the +usual manner. + :line Here are examples of variable definitions that move the wall position diff --git a/doc/fix_wall_reflect.txt b/doc/fix_wall_reflect.txt index 6e7a07f573..197f84bc25 100644 --- a/doc/fix_wall_reflect.txt +++ b/doc/fix_wall_reflect.txt @@ -94,16 +94,16 @@ in a time-dependent fashion using equal-style "variables"_variable.html. variable ramp equal ramp(0,10) -fix 1 all wall xlo v_ramp 1.0 1.0 2.5 :pre +fix 1 all wall xlo v_ramp :pre variable linear equal vlinear(0,20) -fix 1 all wall xlo v_linear 1.0 1.0 2.5 :pre +fix 1 all wall xlo v_linear :pre variable wiggle equal swiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 :pre +fix 1 all wall xlo v_wiggle :pre variable wiggle equal cwiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 :pre +fix 1 all wall xlo v_wiggle :pre The ramp(lo,hi) function adjusts the wall position linearly from lo to hi over the course of a run. The linear(c0,velocity) function does diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html index 750a34767b..ffec9ec605 100644 --- a/doc/pair_coeff.html +++ b/doc/pair_coeff.html @@ -91,6 +91,8 @@ the pair_style command, and coefficients specified by the associated

      • pair_style airebo - AIREBO potential of Stuart
      • pair_style born - Born-Mayer-Huggins potential
      • pair_style born/coul/long - Born-Mayer-Huggins with long-range Coulomb +
      • pair_style brownian - Brownian potential for Fast Lubrication Dynamics +
      • pair_style brownian/poly - Brownian potential for Fast Lubrication Dynamics with polydispersity
      • pair_style buck - Buckingham potential
      • pair_style buck/coul/cut - Buckingham with cutoff Coulomb
      • pair_style buck/coul/long - Buckingham with long-range Coulomb @@ -131,6 +133,9 @@ the pair_style command, and coefficients specified by the associated
      • pair_style lj/smooth - smoothed Lennard-Jones potential
      • pair_style lj96/cut - Lennard-Jones 9/6 potential
      • pair_style lubricate - hydrodynamic lubrication forces +
      • pair_style lubricate/poly - hydrodynamic lubrication forces with polydispersity +
      • pair_style lubricateU - hydrodynamic lubrication forces for Fast Lubrication Dynamics +
      • pair_style lubricateU/poly - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity
      • pair_style meam - modified embedded atom method (MEAM)
      • pair_style morse - Morse potential
      • pair_style peri/lps - peridynamic LPS potential diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt index 02aebc35f6..c9b9881946 100644 --- a/doc/pair_coeff.txt +++ b/doc/pair_coeff.txt @@ -88,6 +88,8 @@ the pair_style command, and coefficients specified by the associated "pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart "pair_style born"_pair_born.html - Born-Mayer-Huggins potential "pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulomb +"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics +"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity "pair_style buck"_pair_buck.html - Buckingham potential "pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb "pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb @@ -128,6 +130,9 @@ the pair_style command, and coefficients specified by the associated "pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential "pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential "pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces +"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity +"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics +"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity "pair_style meam"_pair_meam.html - modified embedded atom method (MEAM) "pair_style morse"_pair_morse.html - Morse potential "pair_style peri/lps"_pair_peri.html - peridynamic LPS potential diff --git a/doc/pair_lubricate.html b/doc/pair_lubricate.html deleted file mode 100644 index 0605657b2c..0000000000 --- a/doc/pair_lubricate.html +++ /dev/null @@ -1,178 +0,0 @@ - -
        LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands -
        - - - - - - -
        - -

        pair_style lubricate command -

        -

        pair_style lubricate/omp command -

        -

        Syntax: -

        -
        pair_style lubricate mu squeeze shear pump twist cutinner cutoff T_target seed 
        -
        -
        • mu = dynamic viscosity (dynamic viscosity units) -
        • squeeze = 0/1 for squeeze force off/on -
        • shear = 0/1 for shear force off/on -
        • pump = 0/1 for pump force off/on -
        • twist = 0/1 for twist force off/on -
        • cutinner = (distance units) -
        • cutoff = outer cutoff for interactions (distance units) -
        • T_target = desired temperature (temperature units) -
        • seed = random number seed (positive integer) -
        -

        Examples: -

        -
        pair_style lubricate 1.5 1 1 1 0 2.3 2.4 1.3 5878598
        -pair_coeff 1 1 1.8 2.0
        -pair_coeff * * 
        -
        -
        pair_style lubricate 1.0 1 1 1 0 2.3 2.4 1.3 5878598
        -pair_coeff * *
        -variable mu equal ramp(1,2)
        -fix 1 all adapt 1 pair lubricate mu * * v_mu 
        -
        -

        Description: -

        -

        Style lubricate computes pairwise interactions between mono-disperse -spherical particles via this formula from (Ball and Melrose) -

        -
        -
        -

        which represents the dissipation W between two nearby particles due to -their relative velocities in the presence of a background solvent with -viscosity mu. Note that this is dynamic viscosity which has units of -mass/distance/time, not kinematic viscosity. -

        -

        The viscosity mu can be varied in a time-dependent manner over the -course of a simluation, in which case in which case the pair_style -setting for mu will be overridden. See the fix adapt -command for details. -

        -

        Rc is the outer cutoff specified in the pair_style command, the -translational velocities of the 2 particles are v1 and v2, the angular -velocities are w1 and w2, and n is the unit vector in the direction -from particle 1 to 2. The 4 terms represent four modes of pairwise -interaction: squeezing, shearing, pumping, and twisting. The 4 flags -in the pair_style command turn on or off each of these modes by -including or excluding each term. The 4 coefficients on each term are -functions of the separation distance of the particles and the -viscosity. Details are given in (Ball and Melrose), including -the forces and torques that result from taking derivatives of this -equation with respect to velocity (see Appendix A). -

        -

        Unlike most pair potentials, the two specified cutoffs (cutinner and -cutoff) refer to the surface-to-surface separation between two -particles, not center-to-center distance. Currently, this pair style -can only be used for mono-disperse extended spheres (same radii), so -that separation is r_ij - 2*radius, where r_ij is the center-to-center -distance between the particles. Within the inner cutoff cutinner, -the forces and torques are evaluated at a separation of cutinner. The -outer cutoff is the separation distance beyond which the pair-wise -forces are zero. -

        -

        A Langevin thermostatting term is also added to the pairwise force, -similar to that provided by the fix langevin or -pair_style dpd commands. The target temperature for -the thermostat is the specified T_target. The seed is used for -the random numbers generated for the thermostat. -

        -

        The following coefficients must be defined for each pair of atoms -types via the pair_coeff command as in the examples -above, or in the data file or restart files read by the -read_data or read_restart -commands, or by mixing as described below: -

        -
        • cutinner (distance units) -
        • cutoff (distance units) -
        -

        The two coefficients are optional. If neither is specified, the two -cutoffs specified in the pair_style command are used. Otherwise both -must be specified. -

        -
        - -

        Styles with a cuda, gpu, omp, or opt suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in this section of the manual. -The accelerated styles take the same arguments and should produce the -same results, except for round-off and precision issues. -

        -

        These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT -packages, respectively. They are only enabled if LAMMPS was built with -those packages. See the Making LAMMPS -section for more info. -

        -

        You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the -suffix command-line -switch when you invoke LAMMPS, or you can -use the suffix command in your input script. -

        -

        See this section of the manual for more -instructions on how to use the accelerated styles effectively. -

        -
        - -

        Mixing, shift, table, tail correction, restart, rRESPA info: -

        -

        For atom type pairs I,J and I != J, the two cutoff distances for this -pair style can be mixed. The default mix value is geometric. See -the "pair_modify" command for details. -

        -

        This pair style does not support the pair_modify -shift option for the energy of the pair interaction. -

        -

        The pair_modify table option is not relevant -for this pair style. -

        -

        This pair style does not support the pair_modify -tail option for adding long-range tail corrections to energy and -pressure. -

        -

        This pair style writes its information to binary restart -files, so pair_style and pair_coeff commands do not need -to be specified in an input script that reads a restart file. -

        -

        This pair style can only be used via the pair keyword of the -run_style respa command. It does not support the -inner, middle, outer keywords. -

        -
        - -

        Restrictions: -

        -

        This style is part of the COLLOID package. It is only enabled if -LAMMPS was built with that package. See the Making -LAMMPS section for more info. -

        -

        This pair style requires that atoms be finite-size spheres with a -diameter, as defined by the atom_style sphere -command. -

        -

        Per-particle or per-type polydispersity is not yet supported by this -pair style; all particles must have the same diameter. -

        -

        This pair style requires you to use the communicate vel -yes option so that velocites are stored by ghost -atoms. -

        -

        Related commands: -

        -

        pair_coeff -

        -

        Default: none -

        -
        - - - -

        (Ball) Ball and Melrose, Physica A, 247, 444-472 (1997). -

        - diff --git a/doc/pair_lubricate.txt b/doc/pair_lubricate.txt deleted file mode 100644 index c244dae435..0000000000 --- a/doc/pair_lubricate.txt +++ /dev/null @@ -1,171 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -pair_style lubricate command :h3 -pair_style lubricate/omp command :h3 - -[Syntax:] - -pair_style lubricate mu squeeze shear pump twist cutinner cutoff T_target seed :pre - -mu = dynamic viscosity (dynamic viscosity units) -squeeze = 0/1 for squeeze force off/on -shear = 0/1 for shear force off/on -pump = 0/1 for pump force off/on -twist = 0/1 for twist force off/on -cutinner = (distance units) -cutoff = outer cutoff for interactions (distance units) -T_target = desired temperature (temperature units) -seed = random number seed (positive integer) :ul - -[Examples:] - -pair_style lubricate 1.5 1 1 1 0 2.3 2.4 1.3 5878598 -pair_coeff 1 1 1.8 2.0 -pair_coeff * * :pre - -pair_style lubricate 1.0 1 1 1 0 2.3 2.4 1.3 5878598 -pair_coeff * * -variable mu equal ramp(1,2) -fix 1 all adapt 1 pair lubricate mu * * v_mu :pre - -[Description:] - -Style {lubricate} computes pairwise interactions between mono-disperse -spherical particles via this formula from "(Ball and Melrose)"_#Ball - -:c,image(Eqs/pair_lubricate.jpg) - -which represents the dissipation W between two nearby particles due to -their relative velocities in the presence of a background solvent with -viscosity mu. Note that this is dynamic viscosity which has units of -mass/distance/time, not kinematic viscosity. - -The viscosity mu can be varied in a time-dependent manner over the -course of a simluation, in which case in which case the pair_style -setting for mu will be overridden. See the "fix adapt"_fix_adapt.html -command for details. - -Rc is the outer cutoff specified in the pair_style command, the -translational velocities of the 2 particles are v1 and v2, the angular -velocities are w1 and w2, and n is the unit vector in the direction -from particle 1 to 2. The 4 terms represent four modes of pairwise -interaction: squeezing, shearing, pumping, and twisting. The 4 flags -in the pair_style command turn on or off each of these modes by -including or excluding each term. The 4 coefficients on each term are -functions of the separation distance of the particles and the -viscosity. Details are given in "(Ball and Melrose)"_#Ball, including -the forces and torques that result from taking derivatives of this -equation with respect to velocity (see Appendix A). - -Unlike most pair potentials, the two specified cutoffs (cutinner and -cutoff) refer to the surface-to-surface separation between two -particles, not center-to-center distance. Currently, this pair style -can only be used for mono-disperse extended spheres (same radii), so -that separation is r_ij - 2*radius, where r_ij is the center-to-center -distance between the particles. Within the inner cutoff {cutinner}, -the forces and torques are evaluated at a separation of cutinner. The -outer {cutoff} is the separation distance beyond which the pair-wise -forces are zero. - -A Langevin thermostatting term is also added to the pairwise force, -similar to that provided by the "fix langevin"_fix_langevin.html or -"pair_style dpd"_pair_dpd.html commands. The target temperature for -the thermostat is the specified {T_target}. The {seed} is used for -the random numbers generated for the thermostat. - -The following coefficients must be defined for each pair of atoms -types via the "pair_coeff"_pair_coeff.html command as in the examples -above, or in the data file or restart files read by the -"read_data"_read_data.html or "read_restart"_read_restart.html -commands, or by mixing as described below: - -cutinner (distance units) -cutoff (distance units) :ul - -The two coefficients are optional. If neither is specified, the two -cutoffs specified in the pair_style command are used. Otherwise both -must be specified. - -:line - -Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally -the same as the corresponding style without the suffix. They have -been optimized to run faster, depending on your available hardware, -as discussed in "this section"_Section_accelerate.html of the manual. -The accelerated styles take the same arguments and should produce the -same results, except for round-off and precision issues. - -These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT -packages, respectively. They are only enabled if LAMMPS was built with -those packages. See the "Making LAMMPS"_Section_start.html#start_3 -section for more info. - -You can specify the accelerated styles explicitly in your input script -by including their suffix, or you can use the "-suffix command-line -switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can -use the "suffix"_suffix.html command in your input script. - -See "this section"_Section_accelerate.html of the manual for more -instructions on how to use the accelerated styles effectively. - -:line - -[Mixing, shift, table, tail correction, restart, rRESPA info]: - -For atom type pairs I,J and I != J, the two cutoff distances for this -pair style can be mixed. The default mix value is {geometric}. See -the "pair_modify" command for details. - -This pair style does not support the "pair_modify"_pair_modify.html -shift option for the energy of the pair interaction. - -The "pair_modify"_pair_modify.html table option is not relevant -for this pair style. - -This pair style does not support the "pair_modify"_pair_modify.html -tail option for adding long-range tail corrections to energy and -pressure. - -This pair style writes its information to "binary restart -files"_restart.html, so pair_style and pair_coeff commands do not need -to be specified in an input script that reads a restart file. - -This pair style can only be used via the {pair} keyword of the -"run_style respa"_run_style.html command. It does not support the -{inner}, {middle}, {outer} keywords. - -:line - -[Restrictions:] - -This style is part of the COLLOID package. It is only enabled if -LAMMPS was built with that package. See the "Making -LAMMPS"_Section_start.html#start_3 section for more info. - -This pair style requires that atoms be finite-size spheres with a -diameter, as defined by the "atom_style sphere"_atom_style.html -command. - -Per-particle or per-type polydispersity is not yet supported by this -pair style; all particles must have the same diameter. - -This pair style requires you to use the "communicate vel -yes"_communicate.html option so that velocites are stored by ghost -atoms. - -[Related commands:] - -"pair_coeff"_pair_coeff.html - -[Default:] none - -:line - -:link(Ball) -[(Ball)] Ball and Melrose, Physica A, 247, 444-472 (1997). diff --git a/doc/pair_style.html b/doc/pair_style.html index b00d2360e5..82720df044 100644 --- a/doc/pair_style.html +++ b/doc/pair_style.html @@ -93,6 +93,8 @@ the pair_style command, and coefficients specified by the associated
      • pair_style airebo - AIREBO potential of Stuart
      • pair_style born - Born-Mayer-Huggins potential
      • pair_style born/coul/long - Born-Mayer-Huggins with long-range Coulomb +
      • pair_style brownian - Brownian potential for Fast Lubrication Dynamics +
      • pair_style brownian/poly - Brownian potential for Fast Lubrication Dynamics with polydispersity
      • pair_style buck - Buckingham potential
      • pair_style buck/coul/cut - Buckingham with cutoff Coulomb
      • pair_style buck/coul/long - Buckingham with long-range Coulomb @@ -133,6 +135,9 @@ the pair_style command, and coefficients specified by the associated
      • pair_style lj/smooth - smoothed Lennard-Jones potential
      • pair_style lj96/cut - Lennard-Jones 9/6 potential
      • pair_style lubricate - hydrodynamic lubrication forces +
      • pair_style lubricate/poly - hydrodynamic lubrication forces with polydispersity +
      • pair_style lubricateU - hydrodynamic lubrication forces for Fast Lubrication Dynamics +
      • pair_style lubricateU/poly - hydrodynamic lubrication forces for Fast Lubrication with polydispersity
      • pair_style meam - modified embedded atom method (MEAM)
      • pair_style morse - Morse potential
      • pair_style peri/lps - peridynamic LPS potential diff --git a/doc/pair_style.txt b/doc/pair_style.txt index c450e3272a..4b23d62068 100644 --- a/doc/pair_style.txt +++ b/doc/pair_style.txt @@ -90,6 +90,8 @@ the pair_style command, and coefficients specified by the associated "pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart "pair_style born"_pair_born.html - Born-Mayer-Huggins potential "pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulomb +"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics +"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity "pair_style buck"_pair_buck.html - Buckingham potential "pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb "pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb @@ -130,6 +132,9 @@ the pair_style command, and coefficients specified by the associated "pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential "pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential "pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces +"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity +"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics +"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication with polydispersity "pair_style meam"_pair_meam.html - modified embedded atom method (MEAM) "pair_style morse"_pair_morse.html - Morse potential "pair_style peri/lps"_pair_peri.html - peridynamic LPS potential From 5a03365db1f108d6b6eeae5fbc9827452f6112c4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:46:58 +0000 Subject: [PATCH 228/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7179 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/restart2data.cpp | 71 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/tools/restart2data.cpp b/tools/restart2data.cpp index ad93313648..dc6d0c489a 100644 --- a/tools/restart2data.cpp +++ b/tools/restart2data.cpp @@ -1380,6 +1380,36 @@ void pair(FILE *fp, Data &data, char *style, int flag) } } + } else if (strcmp(style,"brownian") == 0) { + double mu = read_double(fp); + int flag1 = read_int(fp); + double cut_inner_global = read_double(fp); + double cut_global = read_double(fp); + double t_target = read_double(fp); + int seed = read_int(fp); + int offset_flag = read_int(fp); + int mix_flag = read_int(fp); + + if (!flag) return; + + for (i = 1; i <= data.ntypes; i++) + for (j = i; j <= data.ntypes; j++) { + itmp = read_int(fp); + if (i == j && itmp == 0) { + printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j); + exit(1); + } + if (itmp) { + if (i == j) { + double cut_inner = read_double(fp); + double cut = read_double(fp); + } else { + double cut_inner = read_double(fp); + double cut = read_double(fp); + } + } + } + } else if ((strcmp(style,"buck") == 0) || (strcmp(style,"buck/coul/cut") == 0) || (strcmp(style,"buck/coul/long") == 0) || @@ -2024,6 +2054,35 @@ void pair(FILE *fp, Data &data, char *style, int flag) } } + } else if ((strcmp(style,"lubricate2") == 0) || + (strcmp(style,"lubricateU") == 0)) { + double mu = read_double(fp); + int flag = read_int(fp); + double cut_inner_global = read_double(fp); + double cut_global = read_double(fp); + int offset_flag = read_int(fp); + int mix_flag = read_int(fp); + + if (!flag) return; + + for (i = 1; i <= data.ntypes; i++) + for (j = i; j <= data.ntypes; j++) { + itmp = read_int(fp); + if (i == j && itmp == 0) { + printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j); + exit(1); + } + if (itmp) { + if (i == j) { + double cut_inner = read_double(fp); + double cut = read_double(fp); + } else { + double cut_inner = read_double(fp); + double cut = read_double(fp); + } + } + } + } else if (strcmp(style,"meam") == 0) { } else if (strcmp(style,"morse") == 0) { @@ -2100,8 +2159,9 @@ void pair(FILE *fp, Data &data, char *style, int flag) } else if (strcmp(style,"tersoff") == 0) { } else if (strcmp(style,"tersoff/zbl") == 0) { - } else if (strcmp(style,"yukawa") == 0) { - + } else if ((strcmp(style,"yukawa") == 0) || + (strcmp(style,"yukawa/colloid") == 0)) { + double kappa = read_double(fp); double cut_global = read_double(fp); int offset_flag = read_int(fp); @@ -2132,6 +2192,7 @@ void pair(FILE *fp, Data &data, char *style, int flag) } else if ((strcmp(style,"cg/cmm") == 0) || (strcmp(style,"cg/cmm/coul/cut") == 0) || (strcmp(style,"cg/cmm/coul/long") == 0)) { + m = 0; data.cut_lj_global = read_double(fp); data.cut_coul_global = read_double(fp); @@ -2846,6 +2907,7 @@ void Data::write(FILE *fp, FILE *fp2) if ((strcmp(pair_style,"none") != 0) && (strcmp(pair_style,"adp") != 0) && (strcmp(pair_style,"airebo") != 0) && + (strcmp(pair_style,"brownian") != 0) && (strcmp(pair_style,"coul/cut") != 0) && (strcmp(pair_style,"coul/debye") != 0) && (strcmp(pair_style,"coul/long") != 0) && @@ -2857,6 +2919,8 @@ void Data::write(FILE *fp, FILE *fp2) (strcmp(pair_style,"gran/history") != 0) && (strcmp(pair_style,"gran/no_history") != 0) && (strcmp(pair_style,"gran/hertzian") != 0) && + (strcmp(pair_style,"lubricate2") != 0) && + (strcmp(pair_style,"lubricateU") != 0) && (strcmp(pair_style,"meam") != 0) && (strcmp(pair_style,"reax") != 0) && (strcmp(pair_style,"reax/c") != 0) && @@ -2963,7 +3027,8 @@ void Data::write(FILE *fp, FILE *fp2) fprintf(fp,"%d %g\n",i, pair_soft_A[i]); - } else if (strcmp(pair_style,"yukawa") == 0) { + } else if ((strcmp(pair_style,"yukawa") == 0) || + (strcmp(pair_style,"yukawa/colloid") == 0)) { for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i, pair_yukawa_A[i]); From f3018d53bb32618b5e5483eaf3ec816b531ef5dd Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:49:41 +0000 Subject: [PATCH 229/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7180 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-CUDA/atom_vec_atomic_cuda.cpp | 5 +- src/USER-CUDA/cuda.cpp | 75 ++++++++++---------------- src/USER-CUDA/cuda_neigh_list.cpp | 1 + src/USER-CUDA/neigh_full_cuda.cpp | 1 + src/USER-CUDA/verlet_cuda.cpp | 37 ++++++------- 5 files changed, 50 insertions(+), 69 deletions(-) diff --git a/src/USER-CUDA/atom_vec_atomic_cuda.cpp b/src/USER-CUDA/atom_vec_atomic_cuda.cpp index b6bb14422c..f6b2d76b85 100644 --- a/src/USER-CUDA/atom_vec_atomic_cuda.cpp +++ b/src/USER-CUDA/atom_vec_atomic_cuda.cpp @@ -286,14 +286,14 @@ int AtomVecAtomicCuda::pack_exchange(int dim, double *buf) } if(max_nsend==0) grow_copylist(200); - + int nsend_atoms = Cuda_AtomVecAtomicCuda_PackExchangeList(&cuda->shared_data,*maxsend,dim,*buf_pointer); if(nsend_atoms>max_nsend) {grow_copylist(nsend_atoms+100);} if(nsend_atoms*NCUDAEXCHANGE>*maxsend) { grow_send((int) (nsend_atoms+100)*NCUDAEXCHANGE,buf_pointer,0); - Cuda_AtomVecAtomicCuda_PackExchangeList(&cuda->shared_data,*maxsend,dim,*buf_pointer); + Cuda_AtomVecAtomicCuda_PackExchangeList(&cuda->shared_data,*maxsend,dim,*buf_pointer); } int nlocal=atom->nlocal-nsend_atoms; @@ -395,6 +395,7 @@ int AtomVecAtomicCuda::unpack_exchange(double *buf) } } cuda->shared_data.atom.nlocal=nlocal; + if(atom->nlocal!=nlocal) cuda->shared_data.atom.update_nlocal=2; atom->nlocal=nlocal; mfirst+=m; diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp index 819357bc16..438312ee81 100644 --- a/src/USER-CUDA/cuda.cpp +++ b/src/USER-CUDA/cuda.cpp @@ -130,11 +130,11 @@ Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp) downloadtime=0; dotiming=false; - dotestatom = false; - testatom = 0; + dotestatom = false; + testatom = 0; oncpu = true; - self_comm = 0; + self_comm = 0; MYDBG( printf("# CUDA: Cuda::Cuda Done...\n");) //cCudaData } @@ -267,10 +267,10 @@ void Cuda::accelerator(int narg, char** arg) cu_virial = 0; cu_eatom = 0; cu_vatom = 0; - cu_radius = 0; + cu_radius = 0; cu_density = 0; - cu_omega = 0; - cu_torque = 0; + cu_omega = 0; + cu_torque = 0; cu_special = 0; cu_nspecial = 0; @@ -299,8 +299,11 @@ void Cuda::setSharedDataZero() shared_data.atom.q_flag = 0; shared_data.atom.need_eatom = 0; shared_data.atom.need_vatom = 0; + shared_data.atom.update_nmax = 1; + shared_data.atom.update_nlocal = 1; + shared_data.atom.update_neigh = 1; - shared_data.pair.cudable_force = 0; + shared_data.pair.cudable_force = 0; shared_data.pair.collect_forces_later = 0; shared_data.pair.use_block_per_atom = 0; shared_data.pair.override_block_per_atom = -1; @@ -429,14 +432,6 @@ void Cuda::checkResize() if(cu_atom->q_flag) {delete cu_q; cu_q = new cCudaData ((double*)atom->q, & cu_atom->q , atom->nmax );}// cu_q->set_buffer(&(copy_buffer),&(copy_buffersize),true);} -/* - if(force->pair) - if(force->pair->eatom) - {delete cu_eatom; cu_eatom = new cCudaData (force->pair->eatom, & cu_atom->eatom , atom->nmax );}// cu_eatom->set_buffer(&(copy_buffer),&(copy_buffersize),true);} - if(force->pair) - if(force->pair->vatom) - {delete cu_vatom; cu_vatom = new cCudaData ((double*)force->pair->vatom, & cu_atom->vatom , atom->nmax,6 );}// cu_vatom->set_buffer(&(copy_buffer),&(copy_buffersize),true);} -*/ if(atom->radius) { delete cu_radius; cu_radius = new cCudaData (atom->radius , & cu_atom->radius , atom->nmax ); @@ -444,11 +439,6 @@ void Cuda::checkResize() delete cu_omega_rmass; cu_omega_rmass = new cCudaData (omega_rmass , & cu_atom->omega_rmass , atom->nmax*4); } - /* - if(atom->density) - {delete cu_density; cu_density = new cCudaData (atom->density , & cu_atom->density , atom->nmax );} - */ - if(atom->omega) {delete cu_omega; cu_omega = new cCudaData (((double*) atom->omega) , & cu_atom->omega , atom->nmax,3 );} @@ -464,12 +454,10 @@ void Cuda::checkResize() shared_data.atom.special_flag = neighbor->special_flag; shared_data.atom.molecular = atom->molecular; - cu_atom->update_nmax = 2; - cu_atom->nmax = atom->nmax; + cu_atom->update_nmax = 2; + cu_atom->nmax = atom->nmax; - //delete [] x_type; x_type = new X_FLOAT4[atom->nmax]; delete cu_x_type; cu_x_type = new cCudaData (x_type , & cu_atom->x_type , atom->nmax*4); - // shared_data.buffer_new = 2; } if(((cu_xhold==NULL)||(cu_xhold->get_dim()[0]maxhold))&&neighbor->xhold) @@ -488,6 +476,12 @@ void Cuda::checkResize() { cu_map_array = new cCudaData (atom->get_map_array() , & cu_atom->map_array , atom->get_map_size() ); } + else + if(cu_map_array->dev_size()/sizeof(int)get_map_size()) + { + delete cu_map_array; + cu_map_array = new cCudaData (atom->get_map_array() , & cu_atom->map_array , atom->get_map_size() ); + } } @@ -512,11 +506,6 @@ void Cuda::checkResize() if(atom->radius) if(cu_radius->get_host_data() != atom->radius) cu_radius->set_host_data((double*) (atom->radius)); - /* - if(atom->density) - if(cu_density->get_host_data() != atom->density) cu_density->set_host_data((double*) (atom->density)); - */ - if(atom->omega) if(cu_omega->get_host_data() != atom->omega) cu_omega->set_host_data((double*) (atom->omega)); @@ -558,7 +547,7 @@ void Cuda::evsetup_eatom_vatom(int eflag_atom,int vflag_atom) if(not cu_vatom) cu_vatom = new cCudaData ((double*)force->pair->vatom, & (shared_data.atom.vatom) , atom->nmax ,6 );// cu_vatom->set_buffer(&(copy_buffer),&(copy_buffersize),true);} cu_vatom->set_host_data((double*)force->pair->vatom); - cu_vatom->memset_device(0); + cu_vatom->memset_device(0); } } @@ -579,16 +568,9 @@ void Cuda::uploadAll() cu_image->upload(); if(shared_data.atom.q_flag) cu_q ->upload(); - //printf("A3\n"); - //if(shared_data.atom.need_eatom) cu_eatom->upload(); - //printf("A4\n"); - //if(shared_data.atom.need_vatom) cu_vatom->upload(); - //printf("A5\n"); - if(atom->rmass) cu_rmass->upload(); if(atom->radius) cu_radius->upload(); - // if(atom->density) cu_density->upload(); if(atom->omega) cu_omega->upload(); if(atom->torque) cu_torque->upload(); if(atom->special) cu_special->upload(); @@ -631,7 +613,6 @@ void Cuda::downloadAll() if(atom->rmass) cu_rmass->download(); if(atom->radius) cu_radius->download(); - // if(atom->density) cu_density->download(); if(atom->omega) cu_omega->download(); if(atom->torque) cu_torque->download(); if(atom->special) cu_special->download(); @@ -747,13 +728,13 @@ void Cuda::setTimingsZero() shared_data.cuda_timings.neigh_special = 0; //PPPM - shared_data.cuda_timings.pppm_particle_map; - shared_data.cuda_timings.pppm_make_rho; - shared_data.cuda_timings.pppm_brick2fft; - shared_data.cuda_timings.pppm_poisson; - shared_data.cuda_timings.pppm_fillbrick; - shared_data.cuda_timings.pppm_fieldforce; - shared_data.cuda_timings.pppm_compute; + shared_data.cuda_timings.pppm_particle_map = 0; + shared_data.cuda_timings.pppm_make_rho = 0; + shared_data.cuda_timings.pppm_brick2fft = 0; + shared_data.cuda_timings.pppm_poisson = 0; + shared_data.cuda_timings.pppm_fillbrick = 0; + shared_data.cuda_timings.pppm_fieldforce = 0; + shared_data.cuda_timings.pppm_compute = 0; CudaWrapper_CheckUploadTime(true); CudaWrapper_CheckDownloadTime(true); @@ -789,8 +770,8 @@ void Cuda::print_timings() printf(" Exchange MPI \t %lf \n",shared_data.cuda_timings.comm_exchange_mpi); printf(" Exchange Kernel Pack \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_pack); printf(" Exchange Kernel Unpack \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_unpack); - printf(" Exchange Kernel Fill \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_fill); - printf(" Exchange CPU Pack \t %lf \n",shared_data.cuda_timings.comm_exchange_cpu_pack); + printf(" Exchange Kernel Fill \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_fill); + printf(" Exchange CPU Pack \t %lf \n",shared_data.cuda_timings.comm_exchange_cpu_pack); printf(" Exchange Upload \t %lf \n",shared_data.cuda_timings.comm_exchange_upload); printf(" Exchange Download \t %lf \n",shared_data.cuda_timings.comm_exchange_download); printf("\n"); diff --git a/src/USER-CUDA/cuda_neigh_list.cpp b/src/USER-CUDA/cuda_neigh_list.cpp index ef9edf5ef3..01f8e0c6a8 100644 --- a/src/USER-CUDA/cuda_neigh_list.cpp +++ b/src/USER-CUDA/cuda_neigh_list.cpp @@ -111,6 +111,7 @@ void CudaNeighList::dev_alloc() neighbors_inner = new int[sneighlist.maxlocal*sneighlist.maxneighbors]; cu_neighbors_inner = new cCudaData (neighbors_inner , & sneighlist.neighbors_inner , sneighlist.maxlocal*sneighlist.maxneighbors ); } + cuda->shared_data.atom.update_neigh=2; MYDBG( printf("# CUDA: CudaNeighList::dev_alloc() ... end\n"); ) } diff --git a/src/USER-CUDA/neigh_full_cuda.cpp b/src/USER-CUDA/neigh_full_cuda.cpp index 61c9897f4a..14fe153ec9 100644 --- a/src/USER-CUDA/neigh_full_cuda.cpp +++ b/src/USER-CUDA/neigh_full_cuda.cpp @@ -250,6 +250,7 @@ void NeighborCuda::full_bin_cuda(NeighList *list) }*/ list->cuda_list->cu_numneigh->download(); list->cuda_list->cu_ilist->download(); + cuda->shared_data.atom.update_neigh=2; //printf("Done\n"); MYDBG(printf(" # CUDA::NeighFullBinCuda ... end\n");) diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp index fbaa1800a5..0a3ba3ff40 100644 --- a/src/USER-CUDA/verlet_cuda.cpp +++ b/src/USER-CUDA/verlet_cuda.cpp @@ -564,6 +564,7 @@ void VerletCuda::run(int n) cuda->shared_data.atom.reneigh_flag=0; cuda->shared_data.atom.update_nlocal=1; cuda->shared_data.atom.update_nmax=1; + cuda->shared_data.atom.update_neigh=1; cuda->shared_data.domain.update=1; cuda->shared_data.buffer_new=1; cuda->uploadtime=0; @@ -627,14 +628,12 @@ void VerletCuda::run(int n) //start force calculation asynchronus cuda->shared_data.comm.comm_phase=1; - // printf("Pre Force Compute\n"); force->pair->compute(eflag, vflag); timer->stamp(TIME_PAIR); //CudaWrapper_Sync(); //download comm buffers from GPU, perform MPI communication and upload buffers again clock_gettime(CLOCK_REALTIME,&starttime); - // printf("Pre forward_comm(2)\n"); comm->forward_comm(2); clock_gettime(CLOCK_REALTIME,&endtime); cuda->shared_data.cuda_timings.comm_forward_total+= @@ -642,16 +641,13 @@ void VerletCuda::run(int n) timer->stamp(TIME_COMM); //wait for force calculation - //printf("Pre Synch\n"); CudaWrapper_Sync(); timer->stamp(TIME_PAIR); //unpack communication buffers clock_gettime(CLOCK_REALTIME,&starttime); - // printf("Pre forward_comm(3)\n"); comm->forward_comm(3); clock_gettime(CLOCK_REALTIME,&endtime); - // printf("Post forward_comm(3)\n"); cuda->shared_data.cuda_timings.comm_forward_total+= endtime.tv_sec-starttime.tv_sec+1.0*(endtime.tv_nsec-starttime.tv_nsec)/1000000000; @@ -663,11 +659,9 @@ void VerletCuda::run(int n) else { //perform standard forward communication - //printf("Forward_comm\n"); clock_gettime(CLOCK_REALTIME,&starttime); comm->forward_comm(); clock_gettime(CLOCK_REALTIME,&endtime); - //printf("Forward_comm_done\n"); cuda->shared_data.cuda_timings.comm_forward_total+= endtime.tv_sec-starttime.tv_sec+1.0*(endtime.tv_nsec-starttime.tv_nsec)/1000000000; timer->stamp(TIME_COMM); @@ -677,13 +671,13 @@ void VerletCuda::run(int n) else { int nlocalold=cuda->shared_data.atom.nlocal; - //if(firstreneigh) + if(firstreneigh) { cuda->shared_data.atom.update_nlocal=1; - cuda->shared_data.atom.update_nmax=1; + cuda->shared_data.atom.update_nmax=1; firstreneigh=0; } - cuda->shared_data.buffer_new=1; + cuda->shared_data.buffer_new=1; MYDBG( printf("# CUDA VerletCuda::iterate: neighbor\n"); ) cuda->setDomainParams(); if(n_pre_exchange) modify->pre_exchange(); @@ -759,10 +753,10 @@ void VerletCuda::run(int n) cuda->shared_data.cuda_timings.test2+= endtime.tv_sec-starttime.tv_sec+1.0*(endtime.tv_nsec-starttime.tv_nsec)/1000000000; - //rebuild neighbor list - test_atom(testatom,"Pre Neighbor"); + //rebuild neighbor list + test_atom(testatom,"Pre Neighbor"); neighbor->build(); - timer->stamp(TIME_NEIGHBOR); + timer->stamp(TIME_NEIGHBOR); MYDBG( printf("# CUDA VerletCuda::iterate: neighbor done\n"); ) //if bonded interactions are used (in this case collect_forces_later is true), transfer data which only changes upon exchange/border routines from GPU to CPU @@ -772,7 +766,7 @@ void VerletCuda::run(int n) cuda->cu_tag->download(); cuda->cu_type->download(); cuda->cu_mask->download(); - if(cuda->cu_q) cuda->cu_q->download(); + if(cuda->cu_q) cuda->cu_q->download(); } cuda->shared_data.comm.comm_phase=3; } @@ -969,14 +963,16 @@ void VerletCuda::run(int n) test_atom(testatom,"post output"); if(cuda->shared_data.atom.update_nlocal>0) - cuda->shared_data.atom.update_nlocal--; - if(cuda->shared_data.atom.update_nmax>0) - cuda->shared_data.atom.update_nmax--; - if(cuda->shared_data.domain.update>0) + cuda->shared_data.atom.update_nlocal--; + if(cuda->shared_data.atom.update_nmax>0) + cuda->shared_data.atom.update_nmax--; + if(cuda->shared_data.atom.update_neigh>0) + cuda->shared_data.atom.update_neigh--; + if(cuda->shared_data.domain.update>0) cuda->shared_data.domain.update--; - if(cuda->shared_data.buffer_new>0) + if(cuda->shared_data.buffer_new>0) cuda->shared_data.buffer_new--; - cuda->shared_data.atom.reneigh_flag=0; + cuda->shared_data.atom.reneigh_flag=0; } @@ -984,6 +980,7 @@ void VerletCuda::run(int n) cuda->downloadAllNeighborLists(); cuda->shared_data.atom.update_nlocal=1; cuda->shared_data.atom.update_nmax=1; + cuda->shared_data.atom.update_neigh=1; cuda->shared_data.buffer_new=1; cuda->shared_data.domain.update=1; cuda->oncpu = true; From 860bca7d5e5d4d545fc43a3ef776e0bd604b35e9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:49:51 +0000 Subject: [PATCH 230/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7181 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/atom_vec_cuda.cu | 45 +++++++++------ lib/cuda/comm_cuda.cu | 14 +++-- lib/cuda/compute_temp_cuda.cu | 6 +- lib/cuda/compute_temp_cuda_kernel.cu | 14 ++--- lib/cuda/compute_temp_partial_cuda.cu | 4 +- lib/cuda/compute_temp_partial_cuda_kernel.cu | 14 ++--- lib/cuda/cuda_pair.cu | 58 ++++++++++++-------- lib/cuda/domain_kernel.cu | 2 +- lib/cuda/pair_eam_cuda.cu | 24 +++++--- 9 files changed, 108 insertions(+), 73 deletions(-) diff --git a/lib/cuda/atom_vec_cuda.cu b/lib/cuda/atom_vec_cuda.cu index 187718dc36..3bee50d6ef 100644 --- a/lib/cuda/atom_vec_cuda.cu +++ b/lib/cuda/atom_vec_cuda.cu @@ -78,12 +78,12 @@ void Cuda_AtomVecCuda_UpdateNmax(cuda_shared_data* sdata) cudaMemcpyToSymbol(MY_CONST(type) , & sdata->atom.type .dev_data, sizeof(int*) ); cudaMemcpyToSymbol(MY_CONST(mask) , & sdata->atom.mask .dev_data, sizeof(int*) ); cudaMemcpyToSymbol(MY_CONST(image) , & sdata->atom.image.dev_data, sizeof(int*) ); - if(data_mask & Q_MASK) cudaMemcpyToSymbol(MY_CONST(q) , & sdata->atom.q .dev_data, sizeof(F_FLOAT*) ); - if(data_mask & MOLECULE_MASK) cudaMemcpyToSymbol(MY_CONST(molecule) , & sdata->atom.molecule.dev_data, sizeof(int*) ); - if(data_mask & RADIUS_MASK) cudaMemcpyToSymbol(MY_CONST(radius) , & sdata->atom.radius.dev_data, sizeof(int*) ); - if(data_mask & DENSITY_MASK) cudaMemcpyToSymbol(MY_CONST(density) , & sdata->atom.density.dev_data, sizeof(int*) ); - if(data_mask & RMASS_MASK) cudaMemcpyToSymbol(MY_CONST(rmass) , & sdata->atom.rmass.dev_data, sizeof(int*) ); - if(data_mask & OMEGA_MASK) cudaMemcpyToSymbol(MY_CONST(omega) , & sdata->atom.omega.dev_data, sizeof(int*) ); + if(data_mask & Q_MASK) cudaMemcpyToSymbolAsync(MY_CONST(q) , & sdata->atom.q .dev_data, sizeof(F_FLOAT*) ); + if(data_mask & MOLECULE_MASK) cudaMemcpyToSymbolAsync(MY_CONST(molecule) , & sdata->atom.molecule.dev_data, sizeof(int*) ); + if(data_mask & RADIUS_MASK) cudaMemcpyToSymbolAsync(MY_CONST(radius) , & sdata->atom.radius.dev_data, sizeof(int*) ); + if(data_mask & DENSITY_MASK) cudaMemcpyToSymbolAsync(MY_CONST(density) , & sdata->atom.density.dev_data, sizeof(int*) ); + if(data_mask & RMASS_MASK) cudaMemcpyToSymbolAsync(MY_CONST(rmass) , & sdata->atom.rmass.dev_data, sizeof(int*) ); + if(data_mask & OMEGA_MASK) cudaMemcpyToSymbolAsync(MY_CONST(omega) , & sdata->atom.omega.dev_data, sizeof(int*) ); //if(data_mask & NSPECIAL_MASK) cudaMemcpyToSymbol(MY_CONST(nspecial) , & sdata->atom.nspecial.dev_data, sizeof(int*) ); cudaMemcpyToSymbol(MY_CONST(flag) , & sdata->flag, sizeof(int*) ); } @@ -92,12 +92,16 @@ template void Cuda_AtomVecCuda_Init(cuda_shared_data* sdata) { MYDBG( printf("# CUDA: Cuda_AtomVecCuda_Init ... start\n"); ) + if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); + if(sdata->atom.update_nlocal) + cudaMemcpyToSymbolAsync(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); MYDBG( printf("# CUDA: Cuda_AtomVecCuda_Init ... post Nmax\n"); ) - cudaMemcpyToSymbol(MY_CONST(prd) , sdata->domain.prd, 3*sizeof(X_FLOAT)); - cudaMemcpyToSymbol(MY_CONST(sublo) , & sdata->domain.sublo, 3*sizeof(X_FLOAT) ); - cudaMemcpyToSymbol(MY_CONST(subhi) , & sdata->domain.subhi, 3*sizeof(X_FLOAT) ); - cudaMemcpyToSymbol(MY_CONST(flag) , & sdata->flag, sizeof(int*) ); + cudaMemcpyToSymbolAsync(MY_CONST(prd) , sdata->domain.prd, 3*sizeof(X_FLOAT)); + cudaMemcpyToSymbolAsync(MY_CONST(sublo) , & sdata->domain.sublo, 3*sizeof(X_FLOAT) ); + cudaMemcpyToSymbolAsync(MY_CONST(subhi) , & sdata->domain.subhi, 3*sizeof(X_FLOAT) ); + cudaMemcpyToSymbolAsync(MY_CONST(flag) , & sdata->flag, sizeof(int*) ); + cudaThreadSynchronize(); MYDBG( printf("# CUDA: Cuda_AtomVecCuda_Init ... end\n"); ) } @@ -110,7 +114,7 @@ int Cuda_AtomVecCuda_PackComm(cuda_shared_data* sdata,int n,int iswap,void* buf_ if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); if(sdata->atom.update_nlocal) - cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); + cudaMemcpyToSymbolAsync(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); int n_data_items=AtomVecCuda_CountDataItems(data_mask); int size=(n*n_data_items)*sizeof(X_FLOAT); if(sdata->buffer_new or (size>sdata->buffersize)) @@ -265,6 +269,7 @@ template int Cuda_AtomVecCuda_PackExchangeList(cuda_shared_data* sdata,int n,int dim,void* buf_send) { MYDBG( printf("# CUDA: Cuda_AtomVecCuda_PackExchangeList ... start dim %i \n",dim); ) + CUT_CHECK_ERROR("Cuda_AtomVecCuda_PackExchangeList: pre Kernel execution failed"); cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); Cuda_AtomVecCuda_Init(sdata); int size=n*sizeof(double); @@ -280,7 +285,7 @@ int Cuda_AtomVecCuda_PackExchangeList(cuda_shared_data* sdata,int n,int dim,void timespec time1,time2; clock_gettime(CLOCK_REALTIME,&time1); - Cuda_AtomVecCuda_PackExchangeList_Kernel<<>>(n-1,dim); + Cuda_AtomVecCuda_PackExchangeList_Kernel<<>>(n-1,dim); cudaThreadSynchronize(); CUT_CHECK_ERROR("Cuda_AtomVecCuda_PackExchangeList: Kernel execution failed"); @@ -290,7 +295,9 @@ int Cuda_AtomVecCuda_PackExchangeList(cuda_shared_data* sdata,int n,int dim,void cudaMemcpy(buf_send, sdata->buffer, sizeof(double), cudaMemcpyDeviceToHost); int return_value = ((int*) buf_send)[0]; - cudaMemcpy(buf_send, sdata->buffer, (1+return_value)*sizeof(double), cudaMemcpyDeviceToHost); + if(n>1+return_value) + cudaMemcpy(buf_send, sdata->buffer, (1+return_value)*sizeof(double), cudaMemcpyDeviceToHost); + CUT_CHECK_ERROR("Cuda_AtomVecCuda_PackExchangeList: return copy failed"); clock_gettime(CLOCK_REALTIME,&time1); sdata->cuda_timings.comm_exchange_download+= @@ -304,9 +311,11 @@ template int Cuda_AtomVecCuda_PackExchange(cuda_shared_data* sdata,int nsend,void* buf_send,void* copylist) { MYDBG( printf("# CUDA: Cuda_AtomVecCuda_PackExchange ... start \n"); ) + if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); + //if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); - + int n_data_items=AtomVecCuda_CountDataItems(data_mask)+1; int size=(nsend*n_data_items+1)*sizeof(double); if(sdata->buffer_new or (size>sdata->buffersize)) @@ -323,7 +332,7 @@ int Cuda_AtomVecCuda_PackExchange(cuda_shared_data* sdata,int nsend,void* buf_se Cuda_AtomVecCuda_PackExchange_Kernel<<>>(nsend,(int*) copylist); cudaThreadSynchronize(); - CUT_CHECK_ERROR("Cuda_AtomVecCuda_PackExchangeList: Kernel execution failed"); + CUT_CHECK_ERROR("Cuda_AtomVecCuda_PackExchange: Kernel execution failed"); clock_gettime(CLOCK_REALTIME,&time2); sdata->cuda_timings.comm_exchange_kernel_pack+= @@ -335,7 +344,7 @@ int Cuda_AtomVecCuda_PackExchange(cuda_shared_data* sdata,int nsend,void* buf_se sdata->cuda_timings.comm_exchange_download+= time1.tv_sec-time2.tv_sec+1.0*(time1.tv_nsec-time2.tv_nsec)/1000000000; - MYDBG( printf("# CUDA: Cuda_AtomVecCuda_PackExchangeList ... done\n"); ) + MYDBG( printf("# CUDA: Cuda_AtomVecCuda_PackExchange ... done\n"); ) return nsend*n_data_items+1; } @@ -393,6 +402,7 @@ int Cuda_AtomVecCuda_PackBorder(cuda_shared_data* sdata,int nsend,int iswap,void if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); + if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); clock_gettime(CLOCK_REALTIME,&atime2); sdata->cuda_timings.test1+= @@ -451,6 +461,7 @@ int Cuda_AtomVecCuda_PackBorder_Self(cuda_shared_data* sdata,int n,int iswap,int if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); + if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); int n_data_items=AtomVecCuda_CountDataItems(data_mask); @@ -503,7 +514,7 @@ int Cuda_AtomVecCuda_UnpackBorder(cuda_shared_data* sdata,int n,int first,void* if(sdata->atom.update_nmax) Cuda_AtomVecCuda_UpdateNmax(sdata); - //if(sdata->atom.update_nlocal) + if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); clock_gettime(CLOCK_REALTIME,&atime2); sdata->cuda_timings.test1+= diff --git a/lib/cuda/comm_cuda.cu b/lib/cuda/comm_cuda.cu index 0233f3ee13..dc7c01005d 100644 --- a/lib/cuda/comm_cuda.cu +++ b/lib/cuda/comm_cuda.cu @@ -50,12 +50,12 @@ void Cuda_CommCuda_UpdateBuffer(cuda_shared_data* sdata,int n) void Cuda_CommCuda_UpdateNmax(cuda_shared_data* sdata) { - cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(nmax) , & sdata->atom.nmax , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(x) , & sdata->atom.x .dev_data, sizeof(X_FLOAT*) ); - cudaMemcpyToSymbol(MY_CONST(v) , & sdata->atom.v .dev_data, sizeof(X_FLOAT*) ); - cudaMemcpyToSymbol(MY_CONST(f) , & sdata->atom.f .dev_data, sizeof(F_FLOAT*) ); - cudaMemcpyToSymbol(MY_CONST(type) , & sdata->atom.type .dev_data, sizeof(int*) ); + cudaMemcpyToSymbolAsync(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); + cudaMemcpyToSymbolAsync(MY_CONST(nmax) , & sdata->atom.nmax , sizeof(int) ); + cudaMemcpyToSymbolAsync(MY_CONST(x) , & sdata->atom.x .dev_data, sizeof(X_FLOAT*) ); + cudaMemcpyToSymbolAsync(MY_CONST(v) , & sdata->atom.v .dev_data, sizeof(X_FLOAT*) ); + cudaMemcpyToSymbolAsync(MY_CONST(f) , & sdata->atom.f .dev_data, sizeof(F_FLOAT*) ); + cudaMemcpyToSymbolAsync(MY_CONST(type) , & sdata->atom.type .dev_data, sizeof(int*) ); } @@ -444,7 +444,9 @@ int Cuda_CommCuda_BuildSendlist(cuda_shared_data* sdata,int bordergroup,int inee { MYDBG(printf(" # CUDA: CommCuda_BuildSendlist\n");) timespec time1,time2; + if(sdata->atom.update_nmax) Cuda_CommCuda_UpdateNmax(sdata); + if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); if(sdata->buffer_new or (80>sdata->buffersize)) Cuda_CommCuda_UpdateBuffer(sdata,10); diff --git a/lib/cuda/compute_temp_cuda.cu b/lib/cuda/compute_temp_cuda.cu index bb3fa5ce2a..4ade926461 100644 --- a/lib/cuda/compute_temp_cuda.cu +++ b/lib/cuda/compute_temp_cuda.cu @@ -83,8 +83,9 @@ void Cuda_ComputeTempCuda_Vector(cuda_shared_data* sdata, int groupbit,ENERGY_FL cudaThreadSynchronize(); CUT_CHECK_ERROR("Cuda_ComputeTempCuda_Vector: compute_vector Kernel execution failed"); - int oldgrid=grid.x; + int oldgrid=grid.x*grid.y; grid.x=6; + grid.y=1; threads.x=512; Cuda_ComputeTempCuda_Reduce_Kernel<<>> (oldgrid,t); cudaThreadSynchronize(); @@ -111,8 +112,9 @@ void Cuda_ComputeTempCuda_Scalar(cuda_shared_data* sdata, int groupbit,ENERGY_FL cudaThreadSynchronize(); CUT_CHECK_ERROR("Cuda_ComputeTempCuda_Scalar: compute_scalar Kernel execution failed"); - int oldgrid=grid.x; + int oldgrid=grid.x*grid.y; grid.x=1; + grid.y=1; threads.x=512; Cuda_ComputeTempCuda_Reduce_Kernel<<>> (oldgrid,t); cudaThreadSynchronize(); diff --git a/lib/cuda/compute_temp_cuda_kernel.cu b/lib/cuda/compute_temp_cuda_kernel.cu index 3e97148f6b..c5de884cd1 100644 --- a/lib/cuda/compute_temp_cuda_kernel.cu +++ b/lib/cuda/compute_temp_cuda_kernel.cu @@ -42,7 +42,7 @@ __global__ void Cuda_ComputeTempCuda_Scalar_Kernel(int groupbit) ENERGY_FLOAT* buffer=(ENERGY_FLOAT*) _buffer; if(threadIdx.x==0) { - buffer[blockIdx.x]=sharedmem[0]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)]=sharedmem[0]; } } @@ -76,12 +76,12 @@ __global__ void Cuda_ComputeTempCuda_Vector_Kernel(int groupbit) ENERGY_FLOAT* buffer=(ENERGY_FLOAT*) _buffer; if(threadIdx.x==0) { - buffer[blockIdx.x]=sharedmem[0]; - buffer[blockIdx.x+gridDim.x]=sharedmem[blockDim.x]; - buffer[blockIdx.x+2*gridDim.x]=sharedmem[2*blockDim.x]; - buffer[blockIdx.x+3*gridDim.x]=sharedmem[3*blockDim.x]; - buffer[blockIdx.x+4*gridDim.x]=sharedmem[4*blockDim.x]; - buffer[blockIdx.x+5*gridDim.x]=sharedmem[5*blockDim.x]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)]=sharedmem[0]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)+gridDim.x*gridDim.y]=sharedmem[blockDim.x]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)+2*gridDim.x*gridDim.y]=sharedmem[2*blockDim.x]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)+3*gridDim.x*gridDim.y]=sharedmem[3*blockDim.x]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)+4*gridDim.x*gridDim.y]=sharedmem[4*blockDim.x]; + buffer[(blockIdx.x*gridDim.y+blockIdx.y)+5*gridDim.x*gridDim.y]=sharedmem[5*blockDim.x]; } } diff --git a/lib/cuda/compute_temp_partial_cuda.cu b/lib/cuda/compute_temp_partial_cuda.cu index 07e19936f1..94a4fa9ea3 100644 --- a/lib/cuda/compute_temp_partial_cuda.cu +++ b/lib/cuda/compute_temp_partial_cuda.cu @@ -83,7 +83,7 @@ void Cuda_ComputeTempPartialCuda_Vector(cuda_shared_data* sdata, int groupbit,EN cudaThreadSynchronize(); CUT_CHECK_ERROR("Cuda_ComputeTempPartialCuda_Vector: compute_vector Kernel execution failed"); - int oldgrid=grid.x; + int oldgrid=grid.x*grid.y; grid.x=6; threads.x=512; Cuda_ComputeTempPartialCuda_Reduce_Kernel<<>> (oldgrid,t); @@ -111,7 +111,7 @@ void Cuda_ComputeTempPartialCuda_Scalar(cuda_shared_data* sdata, int groupbit,EN cudaThreadSynchronize(); CUT_CHECK_ERROR("Cuda_ComputeTempPartialCuda_Scalar: compute_scalar Kernel execution failed"); - int oldgrid=grid.x; + int oldgrid=grid.x*grid.y; grid.x=1; threads.x=512; Cuda_ComputeTempPartialCuda_Reduce_Kernel<<>> (oldgrid,t); diff --git a/lib/cuda/compute_temp_partial_cuda_kernel.cu b/lib/cuda/compute_temp_partial_cuda_kernel.cu index c14c3a06a2..7c7895ca43 100644 --- a/lib/cuda/compute_temp_partial_cuda_kernel.cu +++ b/lib/cuda/compute_temp_partial_cuda_kernel.cu @@ -42,7 +42,7 @@ __global__ void Cuda_ComputeTempPartialCuda_Scalar_Kernel(int groupbit,int xflag ENERGY_FLOAT* buffer=(ENERGY_FLOAT*) _buffer; if(threadIdx.x==0) { - buffer[blockIdx.x]=sharedmem[0]; + buffer[blockIdx.x*gridDim.y+blockIdx.y]=sharedmem[0]; } } @@ -76,12 +76,12 @@ __global__ void Cuda_ComputeTempPartialCuda_Vector_Kernel(int groupbit,int xflag ENERGY_FLOAT* buffer=(ENERGY_FLOAT*) _buffer; if(threadIdx.x==0) { - buffer[blockIdx.x]=sharedmem[0]; - buffer[blockIdx.x+gridDim.x]=sharedmem[blockDim.x]; - buffer[blockIdx.x+2*gridDim.x]=sharedmem[2*blockDim.x]; - buffer[blockIdx.x+3*gridDim.x]=sharedmem[3*blockDim.x]; - buffer[blockIdx.x+4*gridDim.x]=sharedmem[4*blockDim.x]; - buffer[blockIdx.x+5*gridDim.x]=sharedmem[5*blockDim.x]; + buffer[blockIdx.x*gridDim.y+blockIdx.y]=sharedmem[0]; + buffer[blockIdx.x*gridDim.y+blockIdx.y+gridDim.x*gridDim.y]=sharedmem[blockDim.x]; + buffer[blockIdx.x*gridDim.y+blockIdx.y+2*gridDim.x*gridDim.y]=sharedmem[2*blockDim.x]; + buffer[blockIdx.x*gridDim.y+blockIdx.y+3*gridDim.x*gridDim.y]=sharedmem[3*blockDim.x]; + buffer[blockIdx.x*gridDim.y+blockIdx.y+4*gridDim.x*gridDim.y]=sharedmem[4*blockDim.x]; + buffer[blockIdx.x*gridDim.y+blockIdx.y+5*gridDim.x*gridDim.y]=sharedmem[5*blockDim.x]; } } diff --git a/lib/cuda/cuda_pair.cu b/lib/cuda/cuda_pair.cu index b7b2523529..1d7a439220 100644 --- a/lib/cuda/cuda_pair.cu +++ b/lib/cuda/cuda_pair.cu @@ -208,29 +208,33 @@ void Cuda_UpdateBuffer(cuda_shared_data* sdata,int size) CUT_CHECK_ERROR("Cuda_Pair_UpdateBuffer_AllStyles failed"); } +void Cuda_Pair_UpdateNeighbor_AllStyles(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist) +{ + //Neighbor + cudaMemcpyToSymbol(MY_CONST(neighbor_maxlocal) , & sneighlist->firstneigh.dim[0] , sizeof(unsigned) ); + cudaMemcpyToSymbol(MY_CONST(firstneigh) , & sneighlist->firstneigh.dev_data, sizeof(int*) ); + cudaMemcpyToSymbol(MY_CONST(ilist) , & sneighlist->ilist .dev_data, sizeof(int*) ); + cudaMemcpyToSymbol(MY_CONST(inum) , & sneighlist->inum , sizeof(int) ); + cudaMemcpyToSymbol(MY_CONST(numneigh) , & sneighlist->numneigh .dev_data, sizeof(int*) ); + cudaMemcpyToSymbol(MY_CONST(neighbors) , & sneighlist->neighbors .dev_data, sizeof(int*) ); + cudaMemcpyToSymbol(MY_CONST(maxneighbors) , & sneighlist->maxneighbors , sizeof(int) ); + cudaMemcpyToSymbol(MY_CONST(overlap_comm) , & sdata->overlap_comm, sizeof(int) ); + +if(sdata->overlap_comm) +{ + cudaMemcpyToSymbol(MY_CONST(numneigh_border) , & sneighlist->numneigh_border .dev_data, sizeof(int*)); + cudaMemcpyToSymbol(MY_CONST(numneigh_inner) , & sneighlist->numneigh_inner .dev_data, sizeof(int*)); + cudaMemcpyToSymbol(MY_CONST(neighbors_border) , & sneighlist->neighbors_border.dev_data, sizeof(int*)); + cudaMemcpyToSymbol(MY_CONST(neighbors_inner) , & sneighlist->neighbors_inner .dev_data, sizeof(int*)); + cudaMemcpyToSymbol(MY_CONST(ilist_border) , & sneighlist->ilist_border .dev_data, sizeof(int*)); + cudaMemcpyToSymbol(MY_CONST(inum_border) , & sneighlist->inum_border .dev_data, sizeof(int*) ); +} + +} //Update constants after nmax change which are generally needed by all pair styles void Cuda_Pair_UpdateNmax_AllStyles(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist) { CUT_CHECK_ERROR("Cuda_Pair_UpdateNmax_AllStyles: Begin"); - //Neighbor - cudaMemcpyToSymbol(MY_CONST(neighbor_maxlocal) , & sneighlist->firstneigh.dim[0] , sizeof(unsigned) ); - cudaMemcpyToSymbol(MY_CONST(firstneigh) , & sneighlist->firstneigh.dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(ilist) , & sneighlist->ilist .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(inum) , & sneighlist->inum , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(numneigh) , & sneighlist->numneigh .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(neighbors) , & sneighlist->neighbors .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(maxneighbors) , & sneighlist->maxneighbors , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(overlap_comm) , & sdata->overlap_comm, sizeof(int) ); - - if(sdata->overlap_comm) - { - cudaMemcpyToSymbol(MY_CONST(numneigh_border) , & sneighlist->numneigh_border .dev_data, sizeof(int*)); - cudaMemcpyToSymbol(MY_CONST(numneigh_inner) , & sneighlist->numneigh_inner .dev_data, sizeof(int*)); - cudaMemcpyToSymbol(MY_CONST(neighbors_border) , & sneighlist->neighbors_border.dev_data, sizeof(int*)); - cudaMemcpyToSymbol(MY_CONST(neighbors_inner) , & sneighlist->neighbors_inner .dev_data, sizeof(int*)); - cudaMemcpyToSymbol(MY_CONST(ilist_border) , & sneighlist->ilist_border .dev_data, sizeof(int*)); - cudaMemcpyToSymbol(MY_CONST(inum_border) , & sneighlist->inum_border .dev_data, sizeof(int*) ); - } //System cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); @@ -757,6 +761,8 @@ timespec startpairtime, endpairtime; //Function which is called prior to kernel invocation, determins grid, Binds Textures, updates constant memory if necessary void Cuda_Pair_PreKernel_AllStyles(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist,int eflag, int vflag, dim3& grid, dim3& threads, int& sharedperproc,bool need_q=false,int maxthreads=256) { + if(sdata->atom.update_neigh) + Cuda_Pair_UpdateNeighbor_AllStyles(sdata,sneighlist); if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax_AllStyles(sdata,sneighlist); if(sdata->atom.update_nlocal) @@ -880,7 +886,7 @@ void Cuda_Pair_UpdateNmax(cuda_shared_data* sdata) cudaMemcpyToSymbol(MY_CONST(v_radius) , & sdata->atom.v_radius .dev_data, sizeof(V_FLOAT4*) ); cudaMemcpyToSymbol(MY_CONST(omega) , & sdata->atom.omega .dev_data, sizeof(V_FLOAT*) ); cudaMemcpyToSymbol(MY_CONST(rmass) , & sdata->atom.rmass .dev_data, sizeof(V_FLOAT*) ); - cudaMemcpyToSymbol(MY_CONST(omega_rmass),& sdata->atom.omega_rmass.dev_data, sizeof(V_FLOAT4*) ); + cudaMemcpyToSymbol(MY_CONST(omega_rmass),& sdata->atom.omega_rmass.dev_data, sizeof(V_FLOAT4*) ); CUT_CHECK_ERROR("Cuda_Pair: updateNmax failed"); } @@ -888,9 +894,13 @@ void Cuda_Pair_UpdateNmax(cuda_shared_data* sdata) void Cuda_Pair_GenerateXType(cuda_shared_data* sdata) { MYDBG(printf(" # CUDA: GenerateXType ... start %i %i %i %p %p %p %p\n",sdata->atom.nlocal,sdata->atom.nall,sdata->atom.nmax,sdata->atom.x.dev_data,sdata->atom.x_type.dev_data,sdata->atom.xhold.dev_data,sdata->atom.type.dev_data); ) + if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax(sdata); - cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); + if(sdata->atom.update_nlocal) + { + cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); + cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); + } MYDBG(printf(" # CUDA: GenerateXType ... getgrid\n"); fflush(stdout); ) int3 layout=getgrid(sdata->atom.nall); @@ -907,6 +917,7 @@ void Cuda_Pair_GenerateXType(cuda_shared_data* sdata) void Cuda_Pair_RevertXType(cuda_shared_data* sdata) { MYDBG(printf(" # CUDA: RevertXType ... start\n"); ) + if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax(sdata); cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); @@ -924,6 +935,7 @@ void Cuda_Pair_RevertXType(cuda_shared_data* sdata) void Cuda_Pair_GenerateVRadius(cuda_shared_data* sdata) { MYDBG(printf(" # CUDA: GenerateVRadius ... start %i %i %i %p %p %p %p\n",sdata->atom.nlocal,sdata->atom.nall,sdata->atom.nmax,sdata->atom.x.dev_data,sdata->atom.x_type.dev_data,sdata->atom.xhold.dev_data,sdata->atom.type.dev_data); ) + if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax(sdata); cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); @@ -943,6 +955,7 @@ void Cuda_Pair_GenerateVRadius(cuda_shared_data* sdata) void Cuda_Pair_GenerateOmegaRmass(cuda_shared_data* sdata) { MYDBG(printf(" # CUDA: GenerateOmegaRmass ... start %i %i %i %p %p %p %p\n",sdata->atom.nlocal,sdata->atom.nall,sdata->atom.nmax,sdata->atom.x.dev_data,sdata->atom.x_type.dev_data,sdata->atom.xhold.dev_data,sdata->atom.type.dev_data); ) + if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax(sdata); cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); @@ -961,6 +974,7 @@ void Cuda_Pair_GenerateOmegaRmass(cuda_shared_data* sdata) void Cuda_Pair_BuildXHold(cuda_shared_data* sdata) { + if(sdata->atom.update_nmax) Cuda_Pair_UpdateNmax(sdata); cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); cudaMemcpyToSymbol(MY_CONST(nall) , & sdata->atom.nall , sizeof(int) ); diff --git a/lib/cuda/domain_kernel.cu b/lib/cuda/domain_kernel.cu index ec5ef897c1..fa76974076 100644 --- a/lib/cuda/domain_kernel.cu +++ b/lib/cuda/domain_kernel.cu @@ -205,7 +205,7 @@ __global__ void Domain_PBC_Kernel(int deform_remap,int deform_groupbit,int box_c maxz=sharedmem[0]; __syncthreads(); } - else {minx=lo[2];maxx=hi[2];} + else {minz=lo[2];maxz=hi[2];} if(threadIdx.x==0) { buf=(X_FLOAT*) _buffer; diff --git a/lib/cuda/pair_eam_cuda.cu b/lib/cuda/pair_eam_cuda.cu index 29ad4af271..d97143a0c7 100644 --- a/lib/cuda/pair_eam_cuda.cu +++ b/lib/cuda/pair_eam_cuda.cu @@ -134,18 +134,22 @@ void Cuda_PairEAMCuda_UpdateBuffer(cuda_shared_data* sdata, cuda_shared_neighlis CUT_CHECK_ERROR("Cuda_PairEAMCuda: updateBuffer failed"); } +void Cuda_PairEAMCuda_UpdateNeighbor(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist) +{ +cudaMemcpyToSymbol(MY_CONST(neighbor_maxlocal) , & sneighlist->firstneigh.dim[0] , sizeof(unsigned) ); +cudaMemcpyToSymbol(MY_CONST(firstneigh), & sneighlist->firstneigh.dev_data, sizeof(int*) ); +cudaMemcpyToSymbol(MY_CONST(ilist) , & sneighlist->ilist .dev_data, sizeof(int*) ); +cudaMemcpyToSymbol(MY_CONST(inum) , & sneighlist->inum , sizeof(int) ); +cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); +cudaMemcpyToSymbol(MY_CONST(nmax) , & sdata->atom.nmax , sizeof(int) ); +cudaMemcpyToSymbol(MY_CONST(numneigh) , & sneighlist->numneigh .dev_data, sizeof(int*) ); +cudaMemcpyToSymbol(MY_CONST(neighbors) , & sneighlist->neighbors .dev_data, sizeof(int*) ); +cudaMemcpyToSymbol(MY_CONST(maxneighbors) , & sneighlist->maxneighbors , sizeof(int) ); +} + void Cuda_PairEAMCuda_UpdateNmax(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist) { CUT_CHECK_ERROR("Cuda_PairEAMCuda: before updateNmax failed"); - cudaMemcpyToSymbol(MY_CONST(neighbor_maxlocal) , & sneighlist->firstneigh.dim[0] , sizeof(unsigned) ); - cudaMemcpyToSymbol(MY_CONST(firstneigh), & sneighlist->firstneigh.dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(ilist) , & sneighlist->ilist .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(inum) , & sneighlist->inum , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(nmax) , & sdata->atom.nmax , sizeof(int) ); - cudaMemcpyToSymbol(MY_CONST(numneigh) , & sneighlist->numneigh .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(neighbors) , & sneighlist->neighbors .dev_data, sizeof(int*) ); - cudaMemcpyToSymbol(MY_CONST(maxneighbors) , & sneighlist->maxneighbors , sizeof(int) ); cudaMemcpyToSymbol(MY_CONST(x) , & sdata->atom.x .dev_data, sizeof(X_FLOAT*) ); cudaMemcpyToSymbol(MY_CONST(x_type) , & sdata->atom.x_type .dev_data, sizeof(X_FLOAT4*) ); cudaMemcpyToSymbol(MY_CONST(f) , & sdata->atom.f .dev_data, sizeof(F_FLOAT*) ); @@ -228,6 +232,8 @@ void Cuda_PairEAM1Cuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlis if(sdata->atom.update_nmax) Cuda_PairEAMCuda_UpdateNmax(sdata,sneighlist); + if(sdata->atom.update_neigh) + Cuda_PairEAMCuda_UpdateNeighbor(sdata,sneighlist); if(sdata->atom.update_nlocal) cudaMemcpyToSymbol(MY_CONST(nlocal) , & sdata->atom.nlocal , sizeof(int) ); if(sdata->buffer_new) From 11806a92a1dfcc6e3f075bd49892460306f18708 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 17:52:52 +0000 Subject: [PATCH 231/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7182 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 522b480dc6..cd5b3ed7ef 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "20 Oct 2011" +#define LAMMPS_VERSION "23 Oct 2011" From c6bbdcfbf2af5d717f244495cd3cb3e2b35286e5 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 24 Oct 2011 20:28:02 +0000 Subject: [PATCH 232/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7184 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/pair_line_lj.cpp | 1 + src/ASPHERE/pair_line_lj.h | 4 +- src/ASPHERE/pair_resquared.cpp | 2 + src/ASPHERE/pair_tri_lj.cpp | 3 +- src/ASPHERE/pair_tri_lj.h | 4 +- src/CLASS2/angle_class2.h | 6 +-- src/CLASS2/bond_class2.h | 6 +-- src/CLASS2/improper_class2.h | 6 +-- src/GPU/fix_gpu.cpp | 9 ++-- src/GRANULAR/fix_pour.cpp | 8 +++- src/GRANULAR/fix_wall_gran.h | 8 ++-- src/KSPACE/ewald.cpp | 2 +- src/KSPACE/ewald.h | 10 ++-- src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp | 3 +- src/KSPACE/pppm.cpp | 32 +++++++++---- src/KSPACE/pppm_cg.cpp | 2 +- src/MANYBODY/pair_adp.cpp | 3 +- src/MOLECULE/angle_charmm.h | 6 +-- src/MOLECULE/angle_cosine.h | 6 +-- src/MOLECULE/angle_cosine_delta.h | 2 +- src/MOLECULE/angle_cosine_periodic.h | 6 +-- src/MOLECULE/angle_harmonic.h | 6 +-- src/MOLECULE/angle_table.h | 6 +-- src/MOLECULE/bond_fene.h | 6 +-- src/MOLECULE/bond_fene_expand.h | 6 +-- src/MOLECULE/bond_harmonic.h | 6 +-- src/MOLECULE/bond_morse.h | 6 +-- src/MOLECULE/bond_nonlinear.h | 6 +-- src/MOLECULE/bond_quartic.h | 6 +-- src/MOLECULE/bond_table.h | 6 +-- src/MOLECULE/improper_cvff.h | 6 +-- src/MOLECULE/improper_harmonic.h | 6 +-- src/MOLECULE/improper_umbrella.h | 6 +-- src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp | 2 +- src/SHOCK/fix_wall_piston.cpp | 6 ++- src/USER-MISC/angle_cosine_shift.h | 4 +- src/USER-MISC/angle_cosine_shift_exp.cpp | 2 +- src/USER-MISC/angle_cosine_shift_exp.h | 6 +-- src/USER-MISC/bond_harmonic_shift.h | 6 +-- src/USER-MISC/bond_harmonic_shift_cut.h | 6 +-- src/angle.cpp | 9 ++-- src/angle.h | 1 + src/atom_vec_line.cpp | 11 +++-- src/atom_vec_tri.cpp | 11 +++-- src/bond.cpp | 9 ++-- src/bond.h | 1 + src/dihedral.cpp | 10 ++-- src/domain.cpp | 2 +- src/domain.h | 19 ++++---- src/force.cpp | 51 ++++++++++++++++++--- src/force.h | 3 +- src/improper.cpp | 9 ++-- src/improper.h | 1 + src/input.cpp | 5 +- src/integrate.cpp | 1 + src/integrate.h | 1 + src/kspace.h | 1 + src/math_const.h | 2 + src/min.cpp | 11 +++-- src/min.h | 1 + src/neigh_full.cpp | 32 ++++++------- src/neigh_list.cpp | 9 ++-- src/neigh_request.cpp | 6 +++ src/neigh_request.h | 4 ++ src/neighbor.cpp | 5 +- src/neighbor.h | 2 +- src/pair.cpp | 8 ++-- src/pair.h | 1 + src/respa.cpp | 2 + src/thermo.h | 6 +-- src/verlet.cpp | 2 + 71 files changed, 279 insertions(+), 190 deletions(-) diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp index ca50168be5..2f3f602ba7 100644 --- a/src/ASPHERE/pair_line_lj.cpp +++ b/src/ASPHERE/pair_line_lj.cpp @@ -96,6 +96,7 @@ void PairLineLJ::compute(int eflag, int vflag) // grow discrete list if necessary and initialize if (nall > nmax) { + nmax = nall; memory->destroy(dnum); memory->destroy(dfirst); memory->create(dnum,nall,"pair:dnum"); diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h index b30140acea..4b60c80eaf 100644 --- a/src/ASPHERE/pair_line_lj.h +++ b/src/ASPHERE/pair_line_lj.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairLineLJ : public Pair { public: PairLineLJ(class LAMMPS *); - ~PairLineLJ(); - void compute(int, int); + virtual ~PairLineLJ(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/ASPHERE/pair_resquared.cpp b/src/ASPHERE/pair_resquared.cpp index 13e57fa64e..9fb782b681 100755 --- a/src/ASPHERE/pair_resquared.cpp +++ b/src/ASPHERE/pair_resquared.cpp @@ -133,6 +133,8 @@ void PairRESquared::compute(int eflag, int vflag) // compute if less than cutoff if (rsq < cutsq[itype][jtype]) { + fforce[0] = fforce[1] = fforce[2] = 0.0; + switch (form[itype][jtype]) { case SPHERE_SPHERE: diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp index 0ecf19aee5..dfcdd819ef 100644 --- a/src/ASPHERE/pair_tri_lj.cpp +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -100,6 +100,7 @@ void PairTriLJ::compute(int eflag, int vflag) // grow discrete list if necessary and initialize if (nall > nmax) { + nmax = nall; memory->destroy(dnum); memory->destroy(dfirst); memory->create(dnum,nall,"pair:dnum"); @@ -118,7 +119,7 @@ void PairTriLJ::compute(int eflag, int vflag) itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; - + for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h index a8cf2bf721..fb0028cce0 100644 --- a/src/ASPHERE/pair_tri_lj.h +++ b/src/ASPHERE/pair_tri_lj.h @@ -27,8 +27,8 @@ namespace LAMMPS_NS { class PairTriLJ : public Pair { public: PairTriLJ(class LAMMPS *); - ~PairTriLJ(); - void compute(int, int); + virtual ~PairTriLJ(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/CLASS2/angle_class2.h b/src/CLASS2/angle_class2.h index cbea3cfe7e..f24ecce524 100644 --- a/src/CLASS2/angle_class2.h +++ b/src/CLASS2/angle_class2.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class AngleClass2 : public Angle { public: AngleClass2(class LAMMPS *); - ~AngleClass2(); - void compute(int, int); + virtual ~AngleClass2(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *theta0,*k2,*k3,*k4; double *bb_k,*bb_r1,*bb_r2; double *ba_k1,*ba_k2,*ba_r1,*ba_r2; diff --git a/src/CLASS2/bond_class2.h b/src/CLASS2/bond_class2.h index 2a5a42c648..3c201e923f 100644 --- a/src/CLASS2/bond_class2.h +++ b/src/CLASS2/bond_class2.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondClass2 : public Bond { public: BondClass2(class LAMMPS *); - ~BondClass2(); - void compute(int, int); + virtual ~BondClass2(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *r0,*k2,*k3,*k4; void allocate(); diff --git a/src/CLASS2/improper_class2.h b/src/CLASS2/improper_class2.h index 9a86e9cd86..cbee3ac810 100644 --- a/src/CLASS2/improper_class2.h +++ b/src/CLASS2/improper_class2.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class ImproperClass2 : public Improper { public: ImproperClass2(class LAMMPS *); - ~ImproperClass2(); - void compute(int, int); + virtual ~ImproperClass2(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k0,*chi0; double *aa_k1,*aa_k2,*aa_k3,*aa_theta0_1,*aa_theta0_2,*aa_theta0_3; int *setflag_i,*setflag_aa; diff --git a/src/GPU/fix_gpu.cpp b/src/GPU/fix_gpu.cpp index a444986701..eec1391bfc 100644 --- a/src/GPU/fix_gpu.cpp +++ b/src/GPU/fix_gpu.cpp @@ -43,7 +43,8 @@ extern double lmp_gpu_forces(double **f, double **tor, double *eatom, FixGPU::FixGPU(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (lmp->cuda) error->all(FLERR,"Cannot use fix GPU with USER-CUDA mode enabled"); + if (lmp->cuda) + error->all(FLERR,"Cannot use fix GPU with USER-CUDA mode enabled"); if (narg < 7) error->all(FLERR,"Illegal fix GPU command"); if (strcmp(arg[1],"all") != 0) error->all(FLERR,"Illegal fix GPU command"); @@ -113,10 +114,8 @@ int FixGPU::setmask() void FixGPU::init() { - // Can only have 1 gpu fix that must be the first fix for a run - if ((void*)modify->fix[0] != (void*)this) - error->all(FLERR,"GPU is not the first fix for this run"); - // Hybrid cannot be used with force/neigh option + // hybrid cannot be used with force/neigh option + if (_gpu_mode == GPU_NEIGH) if (force->pair_match("hybrid",1) != NULL || force->pair_match("hybrid/overlay",1) != NULL) diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp index 03a1c3a62a..fe0ce40f31 100644 --- a/src/GRANULAR/fix_pour.cpp +++ b/src/GRANULAR/fix_pour.cpp @@ -168,8 +168,10 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : // assume grav = -magnitude at this point, enforce in init() int ifix; - for (ifix = 0; ifix < modify->nfix; ifix++) + for (ifix = 0; ifix < modify->nfix; ifix++) { if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break; + if (strcmp(modify->fix[ifix]->style,"gravity/omp") == 0) break; + } if (ifix == modify->nfix) error->all(FLERR,"No fix gravity defined for fix pour"); grav = - ((FixGravity *) modify->fix[ifix])->magnitude * force->ftm2v; @@ -267,8 +269,10 @@ void FixPour::init() // else insertion cannot work int ifix; - for (ifix = 0; ifix < modify->nfix; ifix++) + for (ifix = 0; ifix < modify->nfix; ifix++) { if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break; + if (strcmp(modify->fix[ifix]->style,"gravity/omp") == 0) break; + } if (ifix == modify->nfix) error->all(FLERR,"No fix gravity defined for fix pour"); diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index ae260e478e..343511c860 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -27,12 +27,12 @@ namespace LAMMPS_NS { class FixWallGran : public Fix { public: FixWallGran(class LAMMPS *, int, char **); - ~FixWallGran(); + virtual ~FixWallGran(); int setmask(); void init(); void setup(int); - void post_force(int); - void post_force_respa(int, int, int); + virtual void post_force(int); + virtual void post_force_respa(int, int, int); double memory_usage(); void grow_arrays(int); @@ -46,7 +46,7 @@ class FixWallGran : public Fix { int maxsize_restart(); void reset_dt(); - private: + protected: int wallstyle,pairstyle,wiggle,wshear,axis; double kn,kt,gamman,gammat,xmu; double lo,hi,cylradius; diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp index edd030b55b..b6cff3d932 100644 --- a/src/KSPACE/ewald.cpp +++ b/src/KSPACE/ewald.cpp @@ -282,7 +282,7 @@ void Ewald::compute(int eflag, int vflag) for (k = 0; k < kcount; k++) energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - energy -= g_ewald*qsqsum/1.772453851 + + energy -= g_ewald*qsqsum/MY_PIS + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h index 95482cfbfe..cd22f987f7 100644 --- a/src/KSPACE/ewald.h +++ b/src/KSPACE/ewald.h @@ -27,13 +27,13 @@ namespace LAMMPS_NS { class Ewald : public KSpace { public: Ewald(class LAMMPS *, int, char **); - ~Ewald(); + virtual ~Ewald(); void init(); void setup(); - void compute(int, int); + virtual void compute(int, int); double memory_usage(); - private: + protected: double precision; int kcount,kmax,kmax3d,kmax_created; double qqrd2e; @@ -48,9 +48,9 @@ class Ewald : public KSpace { double *sfacrl,*sfacim,*sfacrl_all,*sfacim_all; double ***cs,***sn; - void eik_dot_r(); + virtual void eik_dot_r(); void coeffs(); - void allocate(); + virtual void allocate(); void deallocate(); void slabcorr(int); }; diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp index bc3cfc98dd..ece15c6839 100644 --- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp @@ -400,7 +400,8 @@ void PairLJCutCoulLongTIP4P::init_style() error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires newton pair on"); if (!atom->q_flag) error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires atom attribute q"); - if (strcmp(force->kspace_style,"pppm/tip4p") != 0) + if ( (strcmp(force->kspace_style,"pppm/tip4p") != 0) && + (strcmp(force->kspace_style,"pppm/tip4p/proxy") != 0) ) error->all(FLERR,"Pair style is incompatible with KSpace style"); if (force->bond == NULL) error->all(FLERR,"Must use a bond style with TIP4P potential"); diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 221778e6ee..e2d017a6e5 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -155,7 +155,8 @@ void PPPM::init() qdist = 0.0; - if (strcmp(force->kspace_style,"pppm/tip4p") == 0) { + if ( (strcmp(force->kspace_style,"pppm/tip4p") == 0) || + (strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) { if (force->pair == NULL) error->all(FLERR,"KSpace style is incompatible with Pair style"); double *p_qdist = (double *) force->pair->extract("qdist",itmp); @@ -184,6 +185,16 @@ void PPPM::init() alpha = qdist / (cos(0.5*theta) * blen); } + // if we have a /proxy pppm version check if the pair style is compatible + + if ( (strcmp(force->kspace_style,"pppm/proxy") == 0) || + (strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) { + if (force->pair == NULL) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + if (strstr(force->pair_style,"pppm/") == NULL ) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + } + // compute qsum & qsqsum and warn if not charge-neutral qsum = qsqsum = 0.0; @@ -709,7 +720,7 @@ void PPPM::compute(int eflag, int vflag) energy = energy_all; energy *= 0.5*volume; - energy -= g_ewald*qsqsum/1.772453851 + + energy -= g_ewald*qsqsum/MY_PIS + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } @@ -1515,8 +1526,7 @@ void PPPM::make_rho() // clear 3d density array - FFT_SCALAR *vec = &density_brick[nzlo_out][nylo_out][nxlo_out]; - for (i = 0; i < ngrid; i++) vec[i] = ZEROF; + memset(&(density_brick[nzlo_out][nylo_out][nxlo_out]),0,ngrid*sizeof(FFT_SCALAR)); // loop over my charges, add their contribution to nearby grid points // (nx,ny,nz) = global coords of grid pt to "lower left" of charge @@ -1777,17 +1787,19 @@ void PPPM::compute_rho1d(const FFT_SCALAR &dx, const FFT_SCALAR &dy, const FFT_SCALAR &dz) { int k,l; + FFT_SCALAR r1,r2,r3; for (k = (1-order)/2; k <= order/2; k++) { - rho1d[0][k] = ZEROF; - rho1d[1][k] = ZEROF; - rho1d[2][k] = ZEROF; + r1 = r2 = r3 = ZEROF; for (l = order-1; l >= 0; l--) { - rho1d[0][k] = rho_coeff[l][k] + rho1d[0][k]*dx; - rho1d[1][k] = rho_coeff[l][k] + rho1d[1][k]*dy; - rho1d[2][k] = rho_coeff[l][k] + rho1d[2][k]*dz; + r1 = rho_coeff[l][k] + r1*dx; + r2 = rho_coeff[l][k] + r2*dy; + r3 = rho_coeff[l][k] + r3*dz; } + rho1d[0][k] = r1; + rho1d[1][k] = r2; + rho1d[2][k] = r3; } } diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp index 5f57715f9f..daffb5ff2d 100644 --- a/src/KSPACE/pppm_cg.cpp +++ b/src/KSPACE/pppm_cg.cpp @@ -178,7 +178,7 @@ void PPPMCG::compute(int eflag, int vflag) energy = energy_all; energy *= 0.5*volume; - energy -= g_ewald*qsqsum/1.772453851 + + energy -= g_ewald*qsqsum/MY_PIS + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } diff --git a/src/MANYBODY/pair_adp.cpp b/src/MANYBODY/pair_adp.cpp index 0f6b0a6a9d..952c1b73a5 100644 --- a/src/MANYBODY/pair_adp.cpp +++ b/src/MANYBODY/pair_adp.cpp @@ -1022,8 +1022,7 @@ void PairADP::unpack_reverse_comm(int n, int *list, double *buf) double PairADP::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = Pair::memory_usage(); bytes += 21 * nmax * sizeof(double); return bytes; } diff --git a/src/MOLECULE/angle_charmm.h b/src/MOLECULE/angle_charmm.h index 81d23867b6..affd5f1ec3 100644 --- a/src/MOLECULE/angle_charmm.h +++ b/src/MOLECULE/angle_charmm.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class AngleCharmm : public Angle { public: AngleCharmm(class LAMMPS *); - ~AngleCharmm(); - void compute(int, int); + virtual ~AngleCharmm(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *k,*theta0,*k_ub,*r_ub; void allocate(); diff --git a/src/MOLECULE/angle_cosine.h b/src/MOLECULE/angle_cosine.h index 1f4aabe456..6b73cf50f1 100644 --- a/src/MOLECULE/angle_cosine.h +++ b/src/MOLECULE/angle_cosine.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class AngleCosine : public Angle { public: AngleCosine(class LAMMPS *); - ~AngleCosine(); - void compute(int, int); + virtual ~AngleCosine(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *k; void allocate(); diff --git a/src/MOLECULE/angle_cosine_delta.h b/src/MOLECULE/angle_cosine_delta.h index a6848cc9a5..52399422fc 100644 --- a/src/MOLECULE/angle_cosine_delta.h +++ b/src/MOLECULE/angle_cosine_delta.h @@ -28,7 +28,7 @@ namespace LAMMPS_NS { class AngleCosineDelta : public AngleCosineSquared { public: AngleCosineDelta(class LAMMPS *); - void compute(int, int); + virtual void compute(int, int); double single(int, int, int, int); }; diff --git a/src/MOLECULE/angle_cosine_periodic.h b/src/MOLECULE/angle_cosine_periodic.h index 4fb901ebe5..fa0a56ab89 100644 --- a/src/MOLECULE/angle_cosine_periodic.h +++ b/src/MOLECULE/angle_cosine_periodic.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class AngleCosinePeriodic : public Angle { public: AngleCosinePeriodic(class LAMMPS *); - ~AngleCosinePeriodic(); - void compute(int, int); + virtual ~AngleCosinePeriodic(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *k; int *multiplicity,*b; diff --git a/src/MOLECULE/angle_harmonic.h b/src/MOLECULE/angle_harmonic.h index f91a84f7fa..7c13d926fb 100644 --- a/src/MOLECULE/angle_harmonic.h +++ b/src/MOLECULE/angle_harmonic.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class AngleHarmonic : public Angle { public: AngleHarmonic(class LAMMPS *); - ~AngleHarmonic(); - void compute(int, int); + virtual ~AngleHarmonic(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *k,*theta0; void allocate(); diff --git a/src/MOLECULE/angle_table.h b/src/MOLECULE/angle_table.h index 23ce4874ca..b404408349 100644 --- a/src/MOLECULE/angle_table.h +++ b/src/MOLECULE/angle_table.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class AngleTable : public Angle { public: AngleTable(class LAMMPS *); - ~AngleTable(); - void compute(int, int); + virtual ~AngleTable(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double equilibrium_angle(int); @@ -37,7 +37,7 @@ class AngleTable : public Angle { void read_restart(FILE *); double single(int, int, int, int); - private: + protected: int tabstyle,tablength; double *theta0; diff --git a/src/MOLECULE/bond_fene.h b/src/MOLECULE/bond_fene.h index 25ca928e31..6fb262c332 100644 --- a/src/MOLECULE/bond_fene.h +++ b/src/MOLECULE/bond_fene.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class BondFENE : public Bond { public: BondFENE(class LAMMPS *); - ~BondFENE(); - void compute(int, int); + virtual ~BondFENE(); + virtual void compute(int, int); void coeff(int, char **); void init_style(); double equilibrium_distance(int); @@ -37,7 +37,7 @@ class BondFENE : public Bond { void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double TWO_1_3; double *k,*r0,*epsilon,*sigma; diff --git a/src/MOLECULE/bond_fene_expand.h b/src/MOLECULE/bond_fene_expand.h index a86dfdba14..89f28c4bf3 100644 --- a/src/MOLECULE/bond_fene_expand.h +++ b/src/MOLECULE/bond_fene_expand.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class BondFENEExpand : public Bond { public: BondFENEExpand(class LAMMPS *); - ~BondFENEExpand(); - void compute(int, int); + virtual ~BondFENEExpand(); + virtual void compute(int, int); void coeff(int, char **); void init_style(); double equilibrium_distance(int); @@ -37,7 +37,7 @@ class BondFENEExpand : public Bond { void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double TWO_1_3; double *k,*r0,*epsilon,*sigma,*shift; diff --git a/src/MOLECULE/bond_harmonic.h b/src/MOLECULE/bond_harmonic.h index a4364cc8bb..87eefd6a0d 100644 --- a/src/MOLECULE/bond_harmonic.h +++ b/src/MOLECULE/bond_harmonic.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondHarmonic : public Bond { public: BondHarmonic(class LAMMPS *); - ~BondHarmonic(); - void compute(int, int); + virtual ~BondHarmonic(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *k,*r0; void allocate(); diff --git a/src/MOLECULE/bond_morse.h b/src/MOLECULE/bond_morse.h index 34fbf265cc..1dcf3653e1 100644 --- a/src/MOLECULE/bond_morse.h +++ b/src/MOLECULE/bond_morse.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondMorse : public Bond { public: BondMorse(class LAMMPS *); - ~BondMorse(); - void compute(int, int); + virtual ~BondMorse(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *d0,*alpha,*r0; void allocate(); diff --git a/src/MOLECULE/bond_nonlinear.h b/src/MOLECULE/bond_nonlinear.h index 1390d25193..8d715e2e61 100644 --- a/src/MOLECULE/bond_nonlinear.h +++ b/src/MOLECULE/bond_nonlinear.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondNonlinear : public Bond { public: BondNonlinear(class LAMMPS *); - ~BondNonlinear(); - void compute(int, int); + virtual ~BondNonlinear(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *epsilon,*r0,*lamda; void allocate(); diff --git a/src/MOLECULE/bond_quartic.h b/src/MOLECULE/bond_quartic.h index 67ae294dec..628d2c237b 100644 --- a/src/MOLECULE/bond_quartic.h +++ b/src/MOLECULE/bond_quartic.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class BondQuartic : public Bond { public: BondQuartic(class LAMMPS *); - ~BondQuartic(); - void compute(int, int); + virtual ~BondQuartic(); + virtual void compute(int, int); void coeff(int, char **); void init_style(); double equilibrium_distance(int); @@ -37,7 +37,7 @@ class BondQuartic : public Bond { void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double TWO_1_3; double *k,*b1,*b2,*rc,*u0; diff --git a/src/MOLECULE/bond_table.h b/src/MOLECULE/bond_table.h index f0d289f055..810693262f 100644 --- a/src/MOLECULE/bond_table.h +++ b/src/MOLECULE/bond_table.h @@ -28,8 +28,8 @@ namespace LAMMPS_NS { class BondTable : public Bond { public: BondTable(class LAMMPS *); - ~BondTable(); - void compute(int, int); + virtual ~BondTable(); + virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double equilibrium_distance(int); @@ -37,7 +37,7 @@ class BondTable : public Bond { void read_restart(FILE *); double single(int, double, int, int); - private: + protected: int tabstyle,tablength; double *r0; diff --git a/src/MOLECULE/improper_cvff.h b/src/MOLECULE/improper_cvff.h index ccef917d3a..86de363a15 100644 --- a/src/MOLECULE/improper_cvff.h +++ b/src/MOLECULE/improper_cvff.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class ImproperCvff : public Improper { public: ImproperCvff(class LAMMPS *); - ~ImproperCvff(); - void compute(int, int); + virtual ~ImproperCvff(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k; int *sign,*multiplicity; diff --git a/src/MOLECULE/improper_harmonic.h b/src/MOLECULE/improper_harmonic.h index a14e222d60..b3d5ef81f6 100644 --- a/src/MOLECULE/improper_harmonic.h +++ b/src/MOLECULE/improper_harmonic.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class ImproperHarmonic : public Improper { public: ImproperHarmonic(class LAMMPS *); - ~ImproperHarmonic(); - void compute(int, int); + virtual ~ImproperHarmonic(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *k,*chi; void allocate(); diff --git a/src/MOLECULE/improper_umbrella.h b/src/MOLECULE/improper_umbrella.h index cef7583743..483979826e 100644 --- a/src/MOLECULE/improper_umbrella.h +++ b/src/MOLECULE/improper_umbrella.h @@ -28,13 +28,13 @@ namespace LAMMPS_NS { class ImproperUmbrella : public Improper { public: ImproperUmbrella(class LAMMPS *); - ~ImproperUmbrella(); - void compute(int, int); + virtual ~ImproperUmbrella(); + virtual void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - private: + protected: double *kw, *w0, *C; void allocate(); diff --git a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp index 24db63e579..aee802db21 100644 --- a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp +++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp @@ -162,7 +162,7 @@ void PairLJCutCoulLongTIP4POpt::eval() double r,r2inv,r6inv,forcecoul,forcelj,cforce; double factor_coul,factor_lj; double grij,expm2,prefactor,t,erfc,ddotf; - double xiM[3],xjM[3],v[6],xH1[3],xH2[3]; + double v[6],xH1[3],xH2[3]; double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz; double *x1,*x2; int *ilist,*jlist,*numneigh,**firstneigh; diff --git a/src/SHOCK/fix_wall_piston.cpp b/src/SHOCK/fix_wall_piston.cpp index 2d610ea2e0..3b66583715 100644 --- a/src/SHOCK/fix_wall_piston.cpp +++ b/src/SHOCK/fix_wall_piston.cpp @@ -24,8 +24,10 @@ #include "random_mars.h" #include "force.h" #include "comm.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -203,7 +205,7 @@ void FixWallPiston::post_integrate() } else if (rampNL1flag) { paccelz = maxvz / tott; - angfreq = 6.283185 / (0.5 * tott); + angfreq = MY_2PI / (0.5 * tott); if (zloflag) { zlo = z0 + paccelz * (0.5*tt + 1.0/(angfreq*angfreq) - 1.0/(angfreq*angfreq)*cos(angfreq*t)); @@ -213,7 +215,7 @@ void FixWallPiston::post_integrate() } else if (rampNL2flag) { paccelz = maxvz / tott; - angfreq = 18.84956 / tott; + angfreq = 3.0*MY_2PI / tott; if (zloflag) { zlo = z0 + paccelz * (0.5*tt + 4.0/(3.0*angfreq*angfreq)*(1.0-cos(angfreq*t)) + 1.0/(6.0*angfreq*angfreq)*(1.0-cos(2.0*angfreq*t))); diff --git a/src/USER-MISC/angle_cosine_shift.h b/src/USER-MISC/angle_cosine_shift.h index ce44ea3045..d8b7ea1741 100644 --- a/src/USER-MISC/angle_cosine_shift.h +++ b/src/USER-MISC/angle_cosine_shift.h @@ -28,7 +28,7 @@ namespace LAMMPS_NS { class AngleCosineShift : public Angle { public: AngleCosineShift(class LAMMPS *); - ~AngleCosineShift(); + virtual ~AngleCosineShift(); virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); @@ -36,7 +36,7 @@ class AngleCosineShift : public Angle { void read_restart(FILE *); double single(int, int, int, int); - private: + protected: double *k; double *a; double *theta; diff --git a/src/USER-MISC/angle_cosine_shift_exp.cpp b/src/USER-MISC/angle_cosine_shift_exp.cpp index cd6a4960d9..031cfec563 100644 --- a/src/USER-MISC/angle_cosine_shift_exp.cpp +++ b/src/USER-MISC/angle_cosine_shift_exp.cpp @@ -57,7 +57,7 @@ void AngleCosineShiftExp::compute(int eflag, int vflag) int i1,i2,i3,n,type; double delx1,dely1,delz1,delx2,dely2,delz2; double eangle,f1[3],f3[3],ff; - double rsq1,rsq2,r1,r2,c,s,cc,ss,a11,a12,a22; + double rsq1,rsq2,r1,r2,c,s,a11,a12,a22; double exp2,aa,uumin,cccpsss,cssmscc; eangle = 0.0; diff --git a/src/USER-MISC/angle_cosine_shift_exp.h b/src/USER-MISC/angle_cosine_shift_exp.h index c51ece7c44..50883dc034 100644 --- a/src/USER-MISC/angle_cosine_shift_exp.h +++ b/src/USER-MISC/angle_cosine_shift_exp.h @@ -26,15 +26,15 @@ namespace LAMMPS_NS { class AngleCosineShiftExp : public Angle { public: AngleCosineShiftExp(class LAMMPS *); - ~AngleCosineShiftExp(); - void compute(int, int); + virtual ~AngleCosineShiftExp(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, int, int, int); - private: + protected: bool *doExpansion; double *umin,*a,*opt1; double *theta0; diff --git a/src/USER-MISC/bond_harmonic_shift.h b/src/USER-MISC/bond_harmonic_shift.h index 91bb723323..b3378aea3f 100644 --- a/src/USER-MISC/bond_harmonic_shift.h +++ b/src/USER-MISC/bond_harmonic_shift.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondHarmonicShift : public Bond { public: BondHarmonicShift(class LAMMPS *); - ~BondHarmonicShift(); - void compute(int, int); + virtual ~BondHarmonicShift(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *k,*r0,*r1; void allocate(); diff --git a/src/USER-MISC/bond_harmonic_shift_cut.h b/src/USER-MISC/bond_harmonic_shift_cut.h index 7bb63ca64b..6e957d286c 100644 --- a/src/USER-MISC/bond_harmonic_shift_cut.h +++ b/src/USER-MISC/bond_harmonic_shift_cut.h @@ -28,15 +28,15 @@ namespace LAMMPS_NS { class BondHarmonicShiftCut : public Bond { public: BondHarmonicShiftCut(class LAMMPS *); - ~BondHarmonicShiftCut(); - void compute(int, int); + virtual ~BondHarmonicShiftCut(); + virtual void compute(int, int); void coeff(int, char **); double equilibrium_distance(int); void write_restart(FILE *); void read_restart(FILE *); double single(int, double, int, int); - private: + protected: double *k,*r0,*r1; void allocate(); diff --git a/src/angle.cpp b/src/angle.cpp index 58ba679948..54a3a5d051 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -14,6 +14,7 @@ #include "math.h" #include "angle.h" #include "atom.h" +#include "comm.h" #include "force.h" #include "math_const.h" #include "memory.h" @@ -78,12 +79,12 @@ void Angle::ev_setup(int eflag, int vflag) if (eflag_atom && atom->nmax > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); - memory->create(eatom,maxeatom,"bond:eatom"); + memory->create(eatom,comm->nthreads*maxeatom,"bond:eatom"); } if (vflag_atom && atom->nmax > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); - memory->create(vatom,maxvatom,6,"bond:vatom"); + memory->create(vatom,comm->nthreads*maxvatom,6,"bond:vatom"); } // zero accumulators @@ -216,7 +217,7 @@ void Angle::ev_tally(int i, int j, int k, int nlocal, int newton_bond, double Angle::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = comm->nthreads*maxeatom * sizeof(double); + bytes += comm->nthreads*maxvatom*6 * sizeof(double); return bytes; } diff --git a/src/angle.h b/src/angle.h index 7f25f38289..46ee5e1dc6 100644 --- a/src/angle.h +++ b/src/angle.h @@ -20,6 +20,7 @@ namespace LAMMPS_NS { class Angle : protected Pointers { + friend class ThrOMP; public: int allocated; int *setflag; diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp index ebf8b7d7a8..c49cd6b6ad 100644 --- a/src/atom_vec_line.cpp +++ b/src/atom_vec_line.cpp @@ -17,6 +17,7 @@ #include "string.h" #include "atom_vec_line.h" #include "atom.h" +#include "comm.h" #include "domain.h" #include "modify.h" #include "force.h" @@ -83,6 +84,8 @@ void AtomVecLine::grow(int n) if (n == 0) nmax += DELTA; else nmax = n; atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -90,12 +93,12 @@ void AtomVecLine::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); omega = memory->grow(atom->omega,nmax,3,"atom:omega"); - torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); line = memory->grow(atom->line,nmax,"atom:line"); if (atom->nextra_grow) @@ -1115,12 +1118,12 @@ bigint AtomVecLine::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); - if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); if (atom->memcheck("line")) bytes += memory->usage(line,nmax); bytes += nmax_bonus*sizeof(Bonus); diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp index 03aed7aa65..0f3fbe161a 100644 --- a/src/atom_vec_tri.cpp +++ b/src/atom_vec_tri.cpp @@ -18,6 +18,7 @@ #include "atom_vec_tri.h" #include "math_extra.h" #include "atom.h" +#include "comm.h" #include "domain.h" #include "modify.h" #include "force.h" @@ -84,6 +85,8 @@ void AtomVecTri::grow(int n) if (n == 0) nmax += DELTA; else nmax = n; atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -91,12 +94,12 @@ void AtomVecTri::grow(int n) image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); - f = memory->grow(atom->f,nmax,3,"atom:f"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); - torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); tri = memory->grow(atom->tri,nmax,"atom:tri"); if (atom->nextra_grow) @@ -1547,12 +1550,12 @@ bigint AtomVecTri::memory_usage() if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); - if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); if (atom->memcheck("tri")) bytes += memory->usage(tri,nmax); bytes += nmax_bonus*sizeof(Bonus); diff --git a/src/bond.cpp b/src/bond.cpp index 92310df653..aa168ff45c 100644 --- a/src/bond.cpp +++ b/src/bond.cpp @@ -14,6 +14,7 @@ #include "string.h" #include "bond.h" #include "atom.h" +#include "comm.h" #include "force.h" #include "memory.h" #include "error.h" @@ -80,12 +81,12 @@ void Bond::ev_setup(int eflag, int vflag) if (eflag_atom && atom->nmax > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); - memory->create(eatom,maxeatom,"bond:eatom"); + memory->create(eatom,comm->nthreads*maxeatom,"bond:eatom"); } if (vflag_atom && atom->nmax > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); - memory->create(vatom,maxvatom,6,"bond:vatom"); + memory->create(vatom,comm->nthreads*maxvatom,6,"bond:vatom"); } // zero accumulators @@ -198,7 +199,7 @@ void Bond::ev_tally(int i, int j, int nlocal, int newton_bond, double Bond::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = comm->nthreads*maxeatom * sizeof(double); + bytes += comm->nthreads*maxvatom*6 * sizeof(double); return bytes; } diff --git a/src/bond.h b/src/bond.h index 551d84b51f..29f9862fb7 100644 --- a/src/bond.h +++ b/src/bond.h @@ -20,6 +20,7 @@ namespace LAMMPS_NS { class Bond : protected Pointers { + friend class ThrOMP; public: int allocated; int *setflag; diff --git a/src/dihedral.cpp b/src/dihedral.cpp index 974df81b14..f1a62cba16 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -14,7 +14,7 @@ #include "math.h" #include "dihedral.h" #include "atom.h" -#include "atom.h" +#include "comm.h" #include "force.h" #include "pair.h" #include "memory.h" @@ -82,12 +82,12 @@ void Dihedral::ev_setup(int eflag, int vflag) if (eflag_atom && atom->nmax > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); - memory->create(eatom,maxeatom,"bond:eatom"); + memory->create(eatom,comm->nthreads*maxeatom,"bond:eatom"); } if (vflag_atom && atom->nmax > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); - memory->create(vatom,maxvatom,6,"bond:vatom"); + memory->create(vatom,comm->nthreads*maxvatom,6,"bond:vatom"); } // zero accumulators @@ -242,7 +242,7 @@ void Dihedral::ev_tally(int i1, int i2, int i3, int i4, double Dihedral::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = comm->nthreads*maxeatom * sizeof(double); + bytes += comm->nthreads*maxvatom*6 * sizeof(double); return bytes; } diff --git a/src/domain.cpp b/src/domain.cpp index a1a0045fa9..3140ea6a54 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -603,7 +603,7 @@ void Domain::minimum_image(double *delta) for triclinic, also add/subtract tilt factors in other dims as needed ------------------------------------------------------------------------- */ -void Domain::closest_image(double *xi, double *xj, double *xjimage) +void Domain::closest_image(const double * const xi, const double * const xj, double * const xjimage) { double dx,dy,dz; diff --git a/src/domain.h b/src/domain.h index c07808ca02..1e04ab4ab9 100644 --- a/src/domain.h +++ b/src/domain.h @@ -93,16 +93,15 @@ class Domain : protected Pointers { virtual void set_local_box(); virtual void reset_box(); virtual void pbc(); - virtual void remap(double *, int &); - virtual void remap(double *); - virtual void remap_near(double *, double *); - virtual void unmap(double *, int); - virtual void unmap(double *, int, double *); - virtual int minimum_image_check(double, double, double); - virtual void minimum_image(double &, double &, double &); - virtual void minimum_image(double *); - virtual void closest_image(double *, double *, double *); - + void remap(double *, int &); + void remap(double *); + void remap_near(double *, double *); + void unmap(double *, int); + void unmap(double *, int, double *); + int minimum_image_check(double, double, double); + void minimum_image(double &, double &, double &); + void minimum_image(double *); + void closest_image(const double * const, const double * const, double * const); void set_lattice(int, char **); void add_region(int, char **); void delete_region(int, char **); diff --git a/src/force.cpp b/src/force.cpp index 67b3873309..5a26d16aa0 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -478,24 +478,61 @@ Improper *Force::new_improper(const char *style, const char *suffix, int &sflag) new kspace style ------------------------------------------------------------------------- */ -void Force::create_kspace(int narg, char **arg) +void Force::create_kspace(int narg, char **arg, const char *suffix) { delete [] kspace_style; if (kspace) delete kspace; - if (strcmp(arg[0],"none") == 0) kspace = NULL; + int sflag; + kspace = new_kspace(narg,arg,suffix,sflag); + + if (sflag) { + char estyle[256]; + sprintf(estyle,"%s/%s",arg[0],suffix); + int n = strlen(estyle) + 1; + kspace_style = new char[n]; + strcpy(kspace_style,estyle); + } else { + int n = strlen(arg[0]) + 1; + kspace_style = new char[n]; + strcpy(kspace_style,arg[0]); + } +} + +/* ---------------------------------------------------------------------- + generate a kspace class +------------------------------------------------------------------------- */ + +KSpace *Force::new_kspace(int narg, char **arg, const char *suffix, int &sflag) +{ + if (suffix && lmp->suffix_enable) { + sflag = 1; + char estyle[256]; + sprintf(estyle,"%s/%s",arg[0],suffix); + + if (0) return NULL; #define KSPACE_CLASS #define KSpaceStyle(key,Class) \ - else if (strcmp(arg[0],#key) == 0) kspace = new Class(lmp,narg-1,&arg[1]); + else if (strcmp(estyle,#key) == 0) return new Class(lmp,narg-1,&arg[1]); +#include "style_kspace.h" +#undef KSpaceStyle +#undef KSPACE_CLASS + + } + + sflag = 0; + + if (strcmp(arg[0],"none") == 0) return NULL; + +#define KSPACE_CLASS +#define KSpaceStyle(key,Class) \ + else if (strcmp(arg[0],#key) == 0) return new Class(lmp,narg-1,&arg[1]); #include "style_kspace.h" #undef KSPACE_CLASS else error->all(FLERR,"Invalid kspace style"); - - int n = strlen(arg[0]) + 1; - kspace_style = new char[n]; - strcpy(kspace_style,arg[0]); + return NULL; } /* ---------------------------------------------------------------------- diff --git a/src/force.h b/src/force.h index 654b81a3a8..a7089070d2 100644 --- a/src/force.h +++ b/src/force.h @@ -86,7 +86,8 @@ class Force : protected Pointers { void create_improper(const char *, const char *suffix = NULL); class Improper *new_improper(const char *, const char *, int &); - void create_kspace(int, char **); + void create_kspace(int, char **, const char *suffix = NULL); + class KSpace *new_kspace(int, char **, const char *, int &); void set_special(int, char **); void bounds(char *, int, int &, int &); diff --git a/src/improper.cpp b/src/improper.cpp index 8f5ab4d6e3..9a1f47e5ce 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -14,6 +14,7 @@ #include "math.h" #include "improper.h" #include "atom.h" +#include "comm.h" #include "force.h" #include "memory.h" #include "error.h" @@ -76,12 +77,12 @@ void Improper::ev_setup(int eflag, int vflag) if (eflag_atom && atom->nmax > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); - memory->create(eatom,maxeatom,"bond:eatom"); + memory->create(eatom,comm->nthreads*maxeatom,"bond:eatom"); } if (vflag_atom && atom->nmax > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); - memory->create(vatom,maxvatom,6,"bond:vatom"); + memory->create(vatom,comm->nthreads*maxvatom,6,"bond:vatom"); } // zero accumulators @@ -236,7 +237,7 @@ void Improper::ev_tally(int i1, int i2, int i3, int i4, double Improper::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = comm->nthreads*maxeatom * sizeof(double); + bytes += comm->nthreads*maxvatom*6 * sizeof(double); return bytes; } diff --git a/src/improper.h b/src/improper.h index d8310b2475..d766015e34 100644 --- a/src/improper.h +++ b/src/improper.h @@ -20,6 +20,7 @@ namespace LAMMPS_NS { class Improper : protected Pointers { + friend class ThrOMP; public: int allocated; int *setflag; diff --git a/src/input.cpp b/src/input.cpp index 2251335b43..457faf4ac8 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1022,7 +1022,8 @@ void Input::improper_style() void Input::kspace_modify() { - if (force->kspace == NULL) error->all(FLERR,"KSpace style has not yet been set"); + if (force->kspace == NULL) + error->all(FLERR,"KSpace style has not yet been set"); force->kspace->modify_params(narg,arg); } @@ -1030,7 +1031,7 @@ void Input::kspace_modify() void Input::kspace_style() { - force->create_kspace(narg,arg); + force->create_kspace(narg,arg,lmp->suffix); } /* ---------------------------------------------------------------------- */ diff --git a/src/integrate.cpp b/src/integrate.cpp index 80bf89f676..6de4df26c3 100644 --- a/src/integrate.cpp +++ b/src/integrate.cpp @@ -26,6 +26,7 @@ Integrate::Integrate(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) { elist_global = elist_atom = NULL; vlist_global = vlist_atom = NULL; + external_force_clear = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/integrate.h b/src/integrate.h index 8f8942c80c..3c75176a10 100644 --- a/src/integrate.h +++ b/src/integrate.h @@ -33,6 +33,7 @@ class Integrate : protected Pointers { protected: int eflag,vflag; // flags for energy/virial computation int virial_style; // compute virial explicitly or implicitly + int external_force_clear; // clear forces locally or externally int nelist_global,nelist_atom; // # of PE,virial computes to check int nvlist_global,nvlist_atom; diff --git a/src/kspace.h b/src/kspace.h index 3ad2193f11..f77bacfcdc 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -19,6 +19,7 @@ namespace LAMMPS_NS { class KSpace : protected Pointers { + friend class ThrOMP; public: double energy; double virial[6]; diff --git a/src/math_const.h b/src/math_const.h index cf7e8a6112..5cbc2aee28 100644 --- a/src/math_const.h +++ b/src/math_const.h @@ -19,6 +19,8 @@ namespace LAMMPS_NS { namespace MathConst { static const double THIRD = 1.0/3.0; static const double MY_PI = 3.14159265358979323846; // pi + static const double MY_2PI = 6.28318530717958647692; // 2pi + static const double MY_3PI = 9.42477796076937971538; // 3pi static const double MY_PI2 = 1.57079632679489661923; // pi/2 static const double MY_PI4 = 0.78539816339744830962; // pi/4 static const double MY_PIS = 1.77245385090551602729; // sqrt(pi) diff --git a/src/min.cpp b/src/min.cpp index bf83065261..0df114edaf 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -157,7 +157,8 @@ void Min::init() if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) { if (comm->me == 0) - error->warning(FLERR,"Resetting reneighboring criteria during minimization"); + error->warning(FLERR, + "Resetting reneighboring criteria during minimization"); } neighbor->every = 1; @@ -227,9 +228,11 @@ void Min::setup() // remove these restriction eventually if (nextra_global && searchflag == 0) - error->all(FLERR,"Cannot use a damped dynamics min style with fix box/relax"); + error->all(FLERR, + "Cannot use a damped dynamics min style with fix box/relax"); if (nextra_atom && searchflag == 0) - error->all(FLERR,"Cannot use a damped dynamics min style with per-atom DOF"); + error->all(FLERR, + "Cannot use a damped dynamics min style with per-atom DOF"); // atoms may have migrated in comm->exchange() @@ -510,6 +513,8 @@ void Min::force_clear() { int i; + if (external_force_clear) return; + // clear global force array // nall includes ghosts only if either newton flag is set diff --git a/src/min.h b/src/min.h index f367fa7b93..47956059d8 100644 --- a/src/min.h +++ b/src/min.h @@ -49,6 +49,7 @@ class Min : protected Pointers { protected: int eflag,vflag; // flags for energy/virial computation int virial_style; // compute virial explicitly or implicitly + int external_force_clear; // clear forces locally or externally double dmax; // max dist to move any atom in one step int linestyle; // 0 = backtrack, 1 = quadratic diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp index b4b7fd0aeb..f35acdb4e3 100644 --- a/src/neigh_full.cpp +++ b/src/neigh_full.cpp @@ -108,7 +108,7 @@ void Neighbor::full_nsq(NeighList *list) /* ---------------------------------------------------------------------- N^2 search for all neighbors - include neighbors of ghost atoms + include neighbors of ghost atoms, but no "special neighbors" for ghosts every neighbor pair appears in list of both atoms i and j ------------------------------------------------------------------------- */ @@ -187,12 +187,9 @@ void Neighbor::full_nsq_ghost(NeighList *list) dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighghostsq[itype][jtype]) { - if (molecular) { - which = find_special(special[i],nspecial[i],tag[j]); - if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } + + if (rsq <= cutneighghostsq[itype][jtype]) + neighptr[n++] = j; } } @@ -201,7 +198,8 @@ void Neighbor::full_nsq_ghost(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR, + "Neighbor list overflow, boost neigh_modify one or page"); } list->inum = atom->nlocal; @@ -295,7 +293,8 @@ void Neighbor::full_bin(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR, + "Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -304,7 +303,7 @@ void Neighbor::full_bin(NeighList *list) /* ---------------------------------------------------------------------- binned neighbor list construction for all neighbors - include neighbors of ghost atoms + include neighbors of ghost atoms, but no "special neighbors" for ghosts every neighbor pair appears in list of both atoms i and j ------------------------------------------------------------------------- */ @@ -407,13 +406,9 @@ void Neighbor::full_bin_ghost(NeighList *list) dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighghostsq[itype][jtype]) { - if (molecular) { - which = find_special(special[i],nspecial[i],tag[j]); - if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } + + if (rsq <= cutneighghostsq[itype][jtype]) + neighptr[n++] = j; } } } @@ -423,7 +418,8 @@ void Neighbor::full_bin_ghost(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR, + "Neighbor list overflow, boost neigh_modify one or page"); } list->inum = atom->nlocal; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index dbd8f0d4a0..738bd5d7e1 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -15,17 +15,12 @@ #include "neigh_list.h" #include "atom.h" #include "comm.h" +#include "update.h" #include "neighbor.h" #include "neigh_request.h" #include "memory.h" #include "error.h" - - -#include "update.h" - - - using namespace LAMMPS_NS; #define PGDELTA 1 @@ -255,6 +250,8 @@ void NeighList::print_attributes() printf(" %d = occasional\n",rq->occasional); printf(" %d = dnum\n",rq->dnum); printf(" %d = ghost\n",rq->ghost); + printf(" %d = cudable\n",rq->cudable); + printf(" %d = omp\n",rq->omp); printf(" %d = copy\n",rq->copy); printf(" %d = skip\n",rq->skip); printf(" %d = otherlist\n",rq->otherlist); diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index 82c9f0b267..2146009a99 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -44,6 +44,8 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) // default is encode special bond flags // default is no auxiliary floating point values // default is no neighbors of ghosts + // default is no CUDA neighbor list build + // default is no multi-threaded neighbor list build occasional = 0; newton = 0; @@ -51,6 +53,7 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) dnum = 0; ghost = 0; cudable = 0; + omp = 0; // default is no copy or skip @@ -101,6 +104,7 @@ int NeighRequest::identical(NeighRequest *other) if (dnum != other->dnum) same = 0; if (ghost != other->ghost) same = 0; if (cudable != other->cudable) same = 0; + if (omp != other->omp) same = 0; if (copy != other->copy) same = 0; if (same_skip(other) == 0) same = 0; @@ -129,6 +133,7 @@ int NeighRequest::same_kind(NeighRequest *other) if (newton != other->newton) same = 0; if (ghost != other->ghost) same = 0; if (cudable != other->cudable) same = 0; + if (omp != other->omp) same = 0; return same; } @@ -178,4 +183,5 @@ void NeighRequest::copy_request(NeighRequest *other) dnum = other->dnum; ghost = other->ghost; cudable = other->cudable; + omp = other->omp; } diff --git a/src/neigh_request.h b/src/neigh_request.h index afff5966c0..e3dcc915a7 100644 --- a/src/neigh_request.h +++ b/src/neigh_request.h @@ -76,6 +76,10 @@ class NeighRequest : protected Pointers { int cudable; + // 1 if using multi-threaded neighbor list build + + int omp; + // set by neighbor and pair_hybrid after all requests are made // these settings do not change kind value diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 58f8ad94dd..24e4285b50 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1698,9 +1698,8 @@ int Neighbor::coord2bin(double *x, int &ix, int &iy, int &iz) return 1 if should be excluded, 0 if included ------------------------------------------------------------------------- */ -int Neighbor::exclusion(int i, int j, int itype, int jtype, - int *mask, int *molecule) -{ +int Neighbor::exclusion(int i, int j, int itype, int jtype, + int *mask, int *molecule) const { int m; if (nex_type && ex_type[itype][jtype]) return 1; diff --git a/src/neighbor.h b/src/neighbor.h index c2fa635d63..5248c0bd6e 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -164,7 +164,7 @@ class Neighbor : protected Pointers { int coord2bin(double *); // mapping atom coord to a bin int coord2bin(double *, int &, int &, int&); // ditto - int exclusion(int, int, int, int, int *, int *); // test for pair exclusion + int exclusion(int, int, int, int, int *, int *) const; // test for pair exclusion virtual void choose_build(int, class NeighRequest *); void choose_stencil(int, class NeighRequest *); diff --git a/src/pair.cpp b/src/pair.cpp index c839078310..c921fdebdf 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -281,12 +281,12 @@ void Pair::ev_setup(int eflag, int vflag) if (eflag_atom && atom->nmax > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); - memory->create(eatom,maxeatom,"pair:eatom"); + memory->create(eatom,comm->nthreads*maxeatom,"pair:eatom"); } if (vflag_atom && atom->nmax > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); - memory->create(vatom,maxvatom,6,"pair:vatom"); + memory->create(vatom,comm->nthreads*maxvatom,6,"pair:vatom"); } // zero accumulators @@ -1151,7 +1151,7 @@ void Pair::init_bitmap(double inner, double outer, int ntablebits, double Pair::memory_usage() { - double bytes = maxeatom * sizeof(double); - bytes += maxvatom*6 * sizeof(double); + double bytes = comm->nthreads*maxeatom * sizeof(double); + bytes += comm->nthreads*maxvatom*6 * sizeof(double); return bytes; } diff --git a/src/pair.h b/src/pair.h index 7e396bbc50..09800c7d3c 100644 --- a/src/pair.h +++ b/src/pair.h @@ -20,6 +20,7 @@ namespace LAMMPS_NS { class Pair : protected Pointers { friend class BondQuartic; + friend class BondQuarticOMP; friend class DihedralCharmm; friend class DihedralCharmmOMP; friend class FixGPU; diff --git a/src/respa.cpp b/src/respa.cpp index c283b6454c..3e54b58424 100644 --- a/src/respa.cpp +++ b/src/respa.cpp @@ -599,6 +599,8 @@ void Respa::force_clear(int newtonflag) { int i; + if (external_force_clear) return; + // clear global force array // nall includes ghosts only if newton flag is set diff --git a/src/thermo.h b/src/thermo.h index eeb758b8e7..d68fff887f 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -38,13 +38,13 @@ class Thermo : protected Pointers { int evaluate_keyword(char *, double *); private: - int me; - char *line; - int nfield,nfield_initial; char **keyword; int *vtype; + int nfield,nfield_initial; + int me; + char **format,**format_user; char *format_float_one_def,*format_float_multi_def; char *format_int_one_def,*format_int_multi_def; diff --git a/src/verlet.cpp b/src/verlet.cpp index 7e38367400..c6d53e5240 100644 --- a/src/verlet.cpp +++ b/src/verlet.cpp @@ -308,6 +308,8 @@ void Verlet::force_clear() { int i; + if (external_force_clear) return; + // clear force on all particles // if either newton flag is set, also include ghosts From 424fd114d75f1dbf89596760c4631f8f9b7a1716 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:05:23 +0000 Subject: [PATCH 233/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7185 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MANYBODY/pair_airebo.cpp | 46 +++++++++++++++++++++++++++++++++ src/MANYBODY/pair_airebo.h | 4 +++ src/REAX/pair_reax.cpp | 49 ++++++++++++++++++++++++++++++++++++ src/REAX/pair_reax.h | 4 +++ src/read_restart.cpp | 18 ++++++++----- 5 files changed, 115 insertions(+), 6 deletions(-) diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index 3f0cb6e253..fd0748c92f 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -4237,6 +4237,52 @@ void PairAIREBO::spline_init() for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480; } +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairAIREBO::write_restart(FILE *fp) +{ + write_restart_settings(fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairAIREBO::read_restart(FILE *fp) +{ + read_restart_settings(fp); + allocate(); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairAIREBO::write_restart_settings(FILE *fp) +{ + fwrite(&cutlj,sizeof(double),1,fp); + fwrite(&ljflag,sizeof(int),1,fp); + fwrite(&torflag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairAIREBO::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cutlj,sizeof(double),1,fp); + fread(&ljflag,sizeof(int),1,fp); + fread(&torflag,sizeof(int),1,fp); + } + MPI_Bcast(&cutlj,1,MPI_DOUBLE,0,world); + MPI_Bcast(&ljflag,1,MPI_INT,0,world); + MPI_Bcast(&torflag,1,MPI_INT,0,world); +} + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index 166e1ed4ed..050ccb324e 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -33,6 +33,10 @@ class PairAIREBO : public Pair { 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 *); double memory_usage(); protected: diff --git a/src/REAX/pair_reax.cpp b/src/REAX/pair_reax.cpp index f32281f5f6..ffc8756a7f 100644 --- a/src/REAX/pair_reax.cpp +++ b/src/REAX/pair_reax.cpp @@ -1050,6 +1050,55 @@ void PairREAX::sparse_product(const int &n, const int &nlocal, } } +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairREAX::write_restart(FILE *fp) +{ + write_restart_settings(fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairREAX::read_restart(FILE *fp) +{ + read_restart_settings(fp); + allocate(); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairREAX::write_restart_settings(FILE *fp) +{ + fwrite(&hbcut,sizeof(double),1,fp); + fwrite(&ihbnew,sizeof(int),1,fp); + fwrite(&itripstaball,sizeof(int),1,fp); + fwrite(&precision,sizeof(double),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairREAX::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&hbcut,sizeof(double),1,fp); + fread(&ihbnew,sizeof(int),1,fp); + fread(&itripstaball,sizeof(int),1,fp); + fread(&precision,sizeof(double),1,fp); + } + MPI_Bcast(&hbcut,1,MPI_DOUBLE,0,world); + MPI_Bcast(&ihbnew,1,MPI_INT,0,world); + MPI_Bcast(&itripstaball,1,MPI_INT,0,world); + MPI_Bcast(&precision,1,MPI_DOUBLE,0,world); +} + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ diff --git a/src/REAX/pair_reax.h b/src/REAX/pair_reax.h index a051c97dc0..27d360eb7b 100644 --- a/src/REAX/pair_reax.h +++ b/src/REAX/pair_reax.h @@ -34,6 +34,10 @@ class PairREAX : public Pair { 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 *); double memory_usage(); int pack_comm(int, int *, double *, int, int *); diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 0514cea310..8092eff57c 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -307,7 +307,8 @@ void ReadRestart::command(int narg, char **arg) if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } - if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); + if (natoms != atom->natoms) + error->all(FLERR,"Did not assign all atoms correctly"); if (me == 0) { if (atom->nbonds) { @@ -501,7 +502,8 @@ void ReadRestart::header() int dimension = read_int(); domain->dimension = dimension; if (domain->dimension == 2 && domain->zperiodic == 0) - error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension"); + error->all(FLERR, + "Cannot run 2d simulation with nonperiodic Z dimension"); // read nprocs from restart file, warn if different @@ -531,14 +533,16 @@ void ReadRestart::header() int newton_pair_file = read_int(); if (force->newton_pair != 1) { if (newton_pair_file != force->newton_pair && me == 0) - error->warning(FLERR,"Restart file used different newton pair setting, " + error->warning(FLERR, + "Restart file used different newton pair setting, " "using input script value"); } } else if (flag == NEWTON_BOND) { int newton_bond_file = read_int(); if (force->newton_bond != 1) { if (newton_bond_file != force->newton_bond && me == 0) - error->warning(FLERR,"Restart file used different newton bond setting, " + error->warning(FLERR, + "Restart file used different newton bond setting, " "using restart file value"); } force->newton_bond = newton_bond_file; @@ -707,7 +711,8 @@ void ReadRestart::type_arrays() atom->set_mass(mass); delete [] mass; - } else error->all(FLERR,"Invalid flag in type arrays section of restart file"); + } else error->all(FLERR, + "Invalid flag in type arrays section of restart file"); flag = read_int(); } @@ -778,7 +783,8 @@ void ReadRestart::force_fields() delete [] style; force->improper->read_restart(fp); - } else error->all(FLERR,"Invalid flag in force field section of restart file"); + } else error->all(FLERR, + "Invalid flag in force field section of restart file"); flag = read_int(); } From ac624c1f8259b43a6782c5774e81cd303df2311f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:07:42 +0000 Subject: [PATCH 234/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7186 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_accelerate.html | 2 +- doc/Section_accelerate.txt | 2 +- doc/Section_commands.html | 6 +++--- doc/Section_commands.txt | 2 +- doc/fix_wall_reflect.html | 8 ++++---- doc/fix_wall_reflect.txt | 8 ++++---- doc/fix_wall_srd.html | 8 ++++---- doc/fix_wall_srd.txt | 9 +++++---- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html index 79df7ef875..b8c2b3a62a 100644 --- a/doc/Section_accelerate.html +++ b/doc/Section_accelerate.html @@ -150,7 +150,7 @@ it as follows:

        env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script
         env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script
        -mpirun -x OMP_NUM_THRADS=2 -np 2 lmp_machine -sf omp -in in.script 
        +mpirun -x OMP_NUM_THREADS=2 -np 2 lmp_machine -sf omp -in in.script 
         

        The value of the environment variable OMP_NUM_THREADS determines how many threads per MPI task are launched. All three examples above use diff --git a/doc/Section_accelerate.txt b/doc/Section_accelerate.txt index fc06f3bcd4..4a9d08b001 100644 --- a/doc/Section_accelerate.txt +++ b/doc/Section_accelerate.txt @@ -145,7 +145,7 @@ it as follows: env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script -mpirun -x OMP_NUM_THRADS=2 -np 2 lmp_machine -sf omp -in in.script :pre +mpirun -x OMP_NUM_THREADS=2 -np 2 lmp_machine -sf omp -in in.script :pre The value of the environment variable OMP_NUM_THREADS determines how many threads per MPI task are launched. All three examples above use diff --git a/doc/Section_commands.html b/doc/Section_commands.html index c69566e177..6e1f356a9f 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -438,9 +438,9 @@ package.

        These are accelerated pair styles, which can be used if LAMMPS is diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index e8ca9cf708..e55664c629 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -695,7 +695,7 @@ package"_Section_start.html#start_3. "eff/cut"_pair_eff.html, "lj/coul"_pair_lj_coul.html, "lj/sf"_pair_lj_sf.html, -"reax/c"_pair_reax_c.html +"reax/c"_pair_reax_c.html, "sph/heatconduction"_pair_heatconduction.html, "sph/idealgas"_pair_idealgas.html, "sph/lj"_pair_lj.html, diff --git a/doc/fix_wall_reflect.html b/doc/fix_wall_reflect.html index 1f8bac0797..5e3aaa73aa 100644 --- a/doc/fix_wall_reflect.html +++ b/doc/fix_wall_reflect.html @@ -105,16 +105,16 @@ in a time-dependent fashion using equal-style variables.

        variable ramp equal ramp(0,10)
        -fix 1 all wall xlo v_ramp 1.0 1.0 2.5 
        +fix 1 all wall/reflect xlo v_ramp 
         
        variable linear equal vlinear(0,20)
        -fix 1 all wall xlo v_linear 1.0 1.0 2.5 
        +fix 1 all wall/reflect xlo v_linear 
         
        variable wiggle equal swiggle(0.0,5.0,3.0)
        -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 
        +fix 1 all wall/reflect xlo v_wiggle  
         
        variable wiggle equal cwiggle(0.0,5.0,3.0)
        -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 
        +fix 1 all wall/reflect xlo v_wiggle 
         

        The ramp(lo,hi) function adjusts the wall position linearly from lo to hi over the course of a run. The linear(c0,velocity) function does diff --git a/doc/fix_wall_reflect.txt b/doc/fix_wall_reflect.txt index 197f84bc25..646e741eae 100644 --- a/doc/fix_wall_reflect.txt +++ b/doc/fix_wall_reflect.txt @@ -94,16 +94,16 @@ in a time-dependent fashion using equal-style "variables"_variable.html. variable ramp equal ramp(0,10) -fix 1 all wall xlo v_ramp :pre +fix 1 all wall/reflect xlo v_ramp :pre variable linear equal vlinear(0,20) -fix 1 all wall xlo v_linear :pre +fix 1 all wall/reflect xlo v_linear :pre variable wiggle equal swiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle :pre +fix 1 all wall/reflect xlo v_wiggle :pre variable wiggle equal cwiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle :pre +fix 1 all wall/reflect xlo v_wiggle :pre The ramp(lo,hi) function adjusts the wall position linearly from lo to hi over the course of a run. The linear(c0,velocity) function does diff --git a/doc/fix_wall_srd.html b/doc/fix_wall_srd.html index 770c03765f..cdb808f73c 100644 --- a/doc/fix_wall_srd.html +++ b/doc/fix_wall_srd.html @@ -139,16 +139,16 @@ in a time-dependent fashion using equal-style variables.

        variable ramp equal ramp(0,10)
        -fix 1 all wall xlo v_ramp 1.0 1.0 2.5 
        +fix 1 all wall/srd xlo v_ramp 
         
        variable linear equal vlinear(0,20)
        -fix 1 all wall xlo v_linear 1.0 1.0 2.5 
        +fix 1 all wall/srd xlo v_linear 
         
        variable wiggle equal swiggle(0.0,5.0,3.0)
        -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 
        +fix 1 all wall/srd xlo v_wiggle  
         
        variable wiggle equal cwiggle(0.0,5.0,3.0)
        -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 
        +fix 1 all wall/srd xlo v_wiggle 
         

        The ramp(lo,hi) function adjusts the wall position linearly from lo to hi over the course of a run. The linear(c0,velocity) function does diff --git a/doc/fix_wall_srd.txt b/doc/fix_wall_srd.txt index c427fe0a8d..596ebe40b8 100644 --- a/doc/fix_wall_srd.txt +++ b/doc/fix_wall_srd.txt @@ -127,17 +127,18 @@ Here are examples of variable definitions that move the wall position in a time-dependent fashion using equal-style "variables"_variable.html. + variable ramp equal ramp(0,10) -fix 1 all wall xlo v_ramp 1.0 1.0 2.5 :pre +fix 1 all wall/srd xlo v_ramp :pre variable linear equal vlinear(0,20) -fix 1 all wall xlo v_linear 1.0 1.0 2.5 :pre +fix 1 all wall/srd xlo v_linear :pre variable wiggle equal swiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 :pre +fix 1 all wall/srd xlo v_wiggle :pre variable wiggle equal cwiggle(0.0,5.0,3.0) -fix 1 all wall xlo v_wiggle 1.0 1.0 2.5 :pre +fix 1 all wall/srd xlo v_wiggle :pre The ramp(lo,hi) function adjusts the wall position linearly from lo to hi over the course of a run. The linear(c0,velocity) function does From b5d15e114ab3cd17dba958f988e34093f87c80ef Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:18:34 +0000 Subject: [PATCH 235/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7187 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/REAX/pair_reax.cpp | 50 +----------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/src/REAX/pair_reax.cpp b/src/REAX/pair_reax.cpp index ffc8756a7f..38aafd89f0 100644 --- a/src/REAX/pair_reax.cpp +++ b/src/REAX/pair_reax.cpp @@ -46,6 +46,7 @@ using namespace LAMMPS_NS; PairREAX::PairREAX(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; no_virial_fdotr_compute = 1; @@ -1050,55 +1051,6 @@ void PairREAX::sparse_product(const int &n, const int &nlocal, } } -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairREAX::write_restart(FILE *fp) -{ - write_restart_settings(fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairREAX::read_restart(FILE *fp) -{ - read_restart_settings(fp); - allocate(); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairREAX::write_restart_settings(FILE *fp) -{ - fwrite(&hbcut,sizeof(double),1,fp); - fwrite(&ihbnew,sizeof(int),1,fp); - fwrite(&itripstaball,sizeof(int),1,fp); - fwrite(&precision,sizeof(double),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairREAX::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&hbcut,sizeof(double),1,fp); - fread(&ihbnew,sizeof(int),1,fp); - fread(&itripstaball,sizeof(int),1,fp); - fread(&precision,sizeof(double),1,fp); - } - MPI_Bcast(&hbcut,1,MPI_DOUBLE,0,world); - MPI_Bcast(&ihbnew,1,MPI_INT,0,world); - MPI_Bcast(&itripstaball,1,MPI_INT,0,world); - MPI_Bcast(&precision,1,MPI_DOUBLE,0,world); -} - /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ From f4aa73f5d532b324631175e42ce2cf394e76b9fa Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:18:45 +0000 Subject: [PATCH 236/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7188 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/REAX/pair_reax.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/REAX/pair_reax.h b/src/REAX/pair_reax.h index 27d360eb7b..a051c97dc0 100644 --- a/src/REAX/pair_reax.h +++ b/src/REAX/pair_reax.h @@ -34,10 +34,6 @@ class PairREAX : public Pair { 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 *); double memory_usage(); int pack_comm(int, int *, double *, int, int *); From fdba4b962b7bccf99a9ea3e8e726f331042e2d42 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:19:06 +0000 Subject: [PATCH 237/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7189 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MANYBODY/pair_airebo.cpp | 47 +----------------------------------- src/MANYBODY/pair_airebo.h | 4 --- src/force.cpp | 1 - src/pair.cpp | 1 + src/pair.h | 1 + src/read_restart.cpp | 6 ++++- 6 files changed, 8 insertions(+), 52 deletions(-) diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index fd0748c92f..6f8ef42511 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -45,6 +45,7 @@ using namespace MathConst; PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; ghostneigh = 1; @@ -4237,52 +4238,6 @@ void PairAIREBO::spline_init() for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480; } -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairAIREBO::write_restart(FILE *fp) -{ - write_restart_settings(fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairAIREBO::read_restart(FILE *fp) -{ - read_restart_settings(fp); - allocate(); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairAIREBO::write_restart_settings(FILE *fp) -{ - fwrite(&cutlj,sizeof(double),1,fp); - fwrite(&ljflag,sizeof(int),1,fp); - fwrite(&torflag,sizeof(int),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairAIREBO::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cutlj,sizeof(double),1,fp); - fread(&ljflag,sizeof(int),1,fp); - fread(&torflag,sizeof(int),1,fp); - } - MPI_Bcast(&cutlj,1,MPI_DOUBLE,0,world); - MPI_Bcast(&ljflag,1,MPI_INT,0,world); - MPI_Bcast(&torflag,1,MPI_INT,0,world); -} - /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index 050ccb324e..166e1ed4ed 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -33,10 +33,6 @@ class PairAIREBO : public Pair { 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 *); double memory_usage(); protected: diff --git a/src/force.cpp b/src/force.cpp index 5a26d16aa0..2600b7dbf7 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -166,7 +166,6 @@ Pair *Force::new_pair(const char *style, const char *suffix, int &sflag) #undef PAIR_CLASS else error->all(FLERR,"Invalid pair style"); - return NULL; } diff --git a/src/pair.cpp b/src/pair.cpp index c921fdebdf..88e938aea2 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -50,6 +50,7 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) comm_forward = comm_reverse = 0; single_enable = 1; + restartinfo = 1; respa_enable = 0; one_coeff = 0; no_virial_fdotr_compute = 0; diff --git a/src/pair.h b/src/pair.h index 09800c7d3c..6a88af5e07 100644 --- a/src/pair.h +++ b/src/pair.h @@ -39,6 +39,7 @@ class Pair : protected Pointers { int comm_reverse; // size of reverse communication (0 if none) int single_enable; // 1 if single() routine exists + int restartinfo; // 1 if pair style writes restart info int respa_enable; // 1 if inner/middle/outer rRESPA routines int one_coeff; // 1 if allows only one coeff * * call int no_virial_fdotr_compute; // 1 if does not invoke virial_fdotr_compute() diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 8092eff57c..dadc29b64f 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -737,7 +737,11 @@ void ReadRestart::force_fields() force->create_pair(style); delete [] style; - force->pair->read_restart(fp); + if (force->pair->restartinfo) force->pair->read_restart(fp); + else { + delete force->pair; + force->pair = NULL; + } } else if (flag == BOND) { if (me == 0) fread(&n,sizeof(int),1,fp); From c8a544cbaed8f7e693c1fa9d7c1121a91efee2b5 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:30:10 +0000 Subject: [PATCH 238/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7190 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-SPH/pair_sph_heatconduction.cpp | 5 +++-- src/USER-SPH/pair_sph_idealgas.cpp | 5 +++-- src/USER-SPH/pair_sph_lj.cpp | 5 +++-- src/USER-SPH/pair_sph_rhosum.cpp | 5 +++-- src/USER-SPH/pair_sph_taitwater.cpp | 5 +++-- src/USER-SPH/pair_sph_taitwater_morris.cpp | 6 +++--- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/USER-SPH/pair_sph_heatconduction.cpp b/src/USER-SPH/pair_sph_heatconduction.cpp index 2eacb71cf2..5f2f3b9002 100644 --- a/src/USER-SPH/pair_sph_heatconduction.cpp +++ b/src/USER-SPH/pair_sph_heatconduction.cpp @@ -26,8 +26,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHHeatConduction::PairSPHHeatConduction(LAMMPS *lmp) : - Pair(lmp) { +PairSPHHeatConduction::PairSPHHeatConduction(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/pair_sph_idealgas.cpp b/src/USER-SPH/pair_sph_idealgas.cpp index a477ed0602..f18cceacd8 100644 --- a/src/USER-SPH/pair_sph_idealgas.cpp +++ b/src/USER-SPH/pair_sph_idealgas.cpp @@ -26,8 +26,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHIdealGas::PairSPHIdealGas(LAMMPS *lmp) : - Pair(lmp) { +PairSPHIdealGas::PairSPHIdealGas(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/pair_sph_lj.cpp b/src/USER-SPH/pair_sph_lj.cpp index 4d73ef03f8..e25e1857d8 100644 --- a/src/USER-SPH/pair_sph_lj.cpp +++ b/src/USER-SPH/pair_sph_lj.cpp @@ -26,8 +26,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHLJ::PairSPHLJ(LAMMPS *lmp) : - Pair(lmp) { +PairSPHLJ::PairSPHLJ(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/pair_sph_rhosum.cpp b/src/USER-SPH/pair_sph_rhosum.cpp index f022e6dc40..3985297dd8 100644 --- a/src/USER-SPH/pair_sph_rhosum.cpp +++ b/src/USER-SPH/pair_sph_rhosum.cpp @@ -29,8 +29,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHRhoSum::PairSPHRhoSum(LAMMPS *lmp) : - Pair(lmp) { +PairSPHRhoSum::PairSPHRhoSum(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; // set comm size needed by this Pair diff --git a/src/USER-SPH/pair_sph_taitwater.cpp b/src/USER-SPH/pair_sph_taitwater.cpp index 86723dd4c8..d709d4cc9b 100644 --- a/src/USER-SPH/pair_sph_taitwater.cpp +++ b/src/USER-SPH/pair_sph_taitwater.cpp @@ -26,8 +26,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHTaitwater::PairSPHTaitwater(LAMMPS *lmp) : - Pair(lmp) { +PairSPHTaitwater::PairSPHTaitwater(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; first = 1; } diff --git a/src/USER-SPH/pair_sph_taitwater_morris.cpp b/src/USER-SPH/pair_sph_taitwater_morris.cpp index d1092cf6e1..1a4dc70cf7 100644 --- a/src/USER-SPH/pair_sph_taitwater_morris.cpp +++ b/src/USER-SPH/pair_sph_taitwater_morris.cpp @@ -26,9 +26,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairSPHTaitwaterMorris::PairSPHTaitwaterMorris(LAMMPS *lmp) : - Pair(lmp) { - +PairSPHTaitwaterMorris::PairSPHTaitwaterMorris(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; first = 1; } From f9847d8111108f1fb2076ea40edb922615cb6378 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:30:15 +0000 Subject: [PATCH 239/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7191 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MEAM/pair_meam.cpp | 1 + src/USER-MISC/pair_cdeam.cpp | 2 ++ src/USER-MISC/pair_edip.cpp | 1 + src/USER-REAXC/pair_reax_c.cpp | 4 ++++ 4 files changed, 8 insertions(+) diff --git a/src/MEAM/pair_meam.cpp b/src/MEAM/pair_meam.cpp index 370a719a2e..fda4c6b3c1 100644 --- a/src/MEAM/pair_meam.cpp +++ b/src/MEAM/pair_meam.cpp @@ -46,6 +46,7 @@ char *keywords[] = {"Ec","alpha","rho0","delta","lattce", PairMEAM::PairMEAM(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; nmax = 0; diff --git a/src/USER-MISC/pair_cdeam.cpp b/src/USER-MISC/pair_cdeam.cpp index b2e6265a2c..4da0065ae7 100644 --- a/src/USER-MISC/pair_cdeam.cpp +++ b/src/USER-MISC/pair_cdeam.cpp @@ -52,6 +52,8 @@ using namespace LAMMPS_NS; PairCDEAM::PairCDEAM(LAMMPS *lmp, int _cdeamVersion) : PairEAM(lmp), PairEAMAlloy(lmp), cdeamVersion(_cdeamVersion) { single_enable = 0; + restartinfo = 0; + rhoB = NULL; D_values = NULL; hcoeff = NULL; diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp index e949742dc7..1be9d8f74f 100755 --- a/src/USER-MISC/pair_edip.cpp +++ b/src/USER-MISC/pair_edip.cpp @@ -46,6 +46,7 @@ using namespace LAMMPS_NS; PairEDIP::PairEDIP(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; nelements = 0; diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index f024d78843..0c30b765d9 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -54,6 +54,10 @@ using namespace LAMMPS_NS; PairReaxC::PairReaxC(LAMMPS *lmp) : Pair(lmp) { + single_enable = 0; + restartinfo = 0; + one_coeff = 1; + system = (reax_system *) memory->smalloc(sizeof(reax_system),"reax:system"); control = (control_params *) From 895680bd32e09ce0e0e8128688939bb1836da8c6 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:30:34 +0000 Subject: [PATCH 240/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7192 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/pair_line_lj.cpp | 1 + src/ASPHERE/pair_tri_lj.cpp | 1 + src/MANYBODY/pair_adp.cpp | 2 ++ src/MANYBODY/pair_comb.cpp | 1 + src/MANYBODY/pair_eam.cpp | 2 ++ src/MANYBODY/pair_eim.cpp | 1 + src/MANYBODY/pair_sw.cpp | 1 + src/MANYBODY/pair_tersoff.cpp | 1 + src/MOLECULE/pair_hbond_dreiding_lj.cpp | 1 + 9 files changed, 11 insertions(+) diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp index 2f3f602ba7..f875158e6e 100644 --- a/src/ASPHERE/pair_line_lj.cpp +++ b/src/ASPHERE/pair_line_lj.cpp @@ -40,6 +40,7 @@ PairLineLJ::PairLineLJ(LAMMPS *lmp) : Pair(lmp) dnum = dfirst = NULL; single_enable = 0; + restartinfo = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp index dfcdd819ef..13650bb611 100644 --- a/src/ASPHERE/pair_tri_lj.cpp +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -41,6 +41,7 @@ PairTriLJ::PairTriLJ(LAMMPS *lmp) : Pair(lmp) dnum = dfirst = NULL; single_enable = 0; + restartinfo = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/MANYBODY/pair_adp.cpp b/src/MANYBODY/pair_adp.cpp index 952c1b73a5..8ce9b57732 100644 --- a/src/MANYBODY/pair_adp.cpp +++ b/src/MANYBODY/pair_adp.cpp @@ -37,6 +37,8 @@ using namespace LAMMPS_NS; PairADP::PairADP(LAMMPS *lmp) : Pair(lmp) { + restartinfo = 0; + nmax = 0; rho = NULL; fp = NULL; diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 2311ea8d1e..a719d33b56 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -47,6 +47,7 @@ using namespace MathConst; PairComb::PairComb(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; nmax = 0; diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp index 39a8292bc1..7ccb61c776 100644 --- a/src/MANYBODY/pair_eam.cpp +++ b/src/MANYBODY/pair_eam.cpp @@ -36,6 +36,8 @@ using namespace LAMMPS_NS; PairEAM::PairEAM(LAMMPS *lmp) : Pair(lmp) { + restartinfo = 0; + nmax = 0; rho = NULL; fp = NULL; diff --git a/src/MANYBODY/pair_eim.cpp b/src/MANYBODY/pair_eim.cpp index c8b324d264..a86fa2557c 100644 --- a/src/MANYBODY/pair_eim.cpp +++ b/src/MANYBODY/pair_eim.cpp @@ -37,6 +37,7 @@ using namespace LAMMPS_NS; PairEIM::PairEIM(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; setfl = NULL; diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 1c708564ac..deae3cb26f 100755 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -41,6 +41,7 @@ using namespace LAMMPS_NS; PairSW::PairSW(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; nelements = 0; diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index 7771bb1982..f284f12fd1 100755 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -42,6 +42,7 @@ using namespace MathConst; PairTersoff::PairTersoff(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; + restartinfo = 0; one_coeff = 1; nelements = 0; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index 104cf83e6d..3ad2c4e351 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -45,6 +45,7 @@ PairHbondDreidingLJ::PairHbondDreidingLJ(LAMMPS *lmp) : Pair(lmp) // due to using map() to find bonded H atoms which are not near donor atom no_virial_fdotr_compute = 1; + restartinfo = 0; nparams = maxparam = 0; params = NULL; From 9e9dcf4f3bf05aa9f26b904fa3c3a267ed855e98 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 15:32:56 +0000 Subject: [PATCH 241/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7193 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index cd5b3ed7ef..4e6050f3a0 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "23 Oct 2011" +#define LAMMPS_VERSION "24 Oct 2011" From 51aef530dedd864b25bd6ed5663a85624c781cf8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 16:05:57 +0000 Subject: [PATCH 242/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7195 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MAKE/Makefile.linux | 6 +++--- src/read_data.cpp | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/MAKE/Makefile.linux b/src/MAKE/Makefile.linux index f0348b3eea..cf39084f2d 100755 --- a/src/MAKE/Makefile.linux +++ b/src/MAKE/Makefile.linux @@ -24,7 +24,7 @@ SIZE = size # LAMMPS ifdef settings, OPTIONAL # see possible settings in doc/Section_start.html#2_2 (step 4) -LMP_INC = -DLAMMPS_GZIP +LMP_INC = -DLAMMPS_GZIP -DLAMMPS_JPEG # MPI library, REQUIRED # see discussion in doc/Section_start.html#2_2 (step 5) @@ -35,7 +35,7 @@ LMP_INC = -DLAMMPS_GZIP MPI_INC = -DMPICH_SKIP_MPICXX MPI_PATH = -MPI_LIB = -lmpich -lpthread +MPI_LIB = -lmpich -lmpl -lpthread # FFT library, OPTIONAL # see discussion in doc/Section_start.html#2_2 (step 6) @@ -57,7 +57,7 @@ FFT_LIB = -lfftw JPG_INC = JPG_PATH = -JPG_LIB = +JPG_LIB = -ljpeg # --------------------------------------------------------------------- # build rules and dependencies diff --git a/src/read_data.cpp b/src/read_data.cpp index 772c3a3824..a96a566b01 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; // customize for new sections #define NSECTIONS 23 // change when add to header::section_keywords -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp) From cbbb66194cebc013fc4d313a77d2176689ffda7e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 16:17:27 +0000 Subject: [PATCH 243/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7196 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MANYBODY/pair_airebo.cpp | 168 ++++++++++++----------------------- src/MANYBODY/pair_airebo.h | 86 ++++++++++++++---- 2 files changed, 127 insertions(+), 127 deletions(-) diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index 6f8ef42511..c2625072cc 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -13,6 +13,8 @@ /* ---------------------------------------------------------------------- Contributing author: Ase Henry (MIT) + Bugfixes and optimizations: + Marcel Fallet & Steve Stuart (Clemson), Axel Kohlmeyer (Temple U) ------------------------------------------------------------------------- */ #include "math.h" @@ -45,7 +47,6 @@ using namespace MathConst; PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; - restartinfo = 0; one_coeff = 1; ghostneigh = 1; @@ -221,7 +222,7 @@ void PairAIREBO::init_style() pgsize = neighbor->pgsize; oneatom = neighbor->oneatom; - if (maxpage == 0) add_pages(0); + if (maxpage == 0) add_pages(); } /* ---------------------------------------------------------------------- @@ -304,7 +305,7 @@ void PairAIREBO::REBO_neigh() int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; - if (nall > maxlocal) { + if (atom->nmax > maxlocal) { maxlocal = atom->nmax; memory->destroy(REBO_numneigh); memory->sfree(REBO_firstneigh); @@ -325,7 +326,7 @@ void PairAIREBO::REBO_neigh() // store all REBO neighs of owned and ghost atoms // scan full neighbor list of I - npage = 0; + int npage = 0; int npnt = 0; for (ii = 0; ii < allnum; ii++) { @@ -334,7 +335,7 @@ void PairAIREBO::REBO_neigh() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == maxpage) add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -1196,60 +1197,6 @@ void PairAIREBO::TORSION(int eflag, int vflag) } } -// ---------------------------------------------------------------------- -// S'(t) and S(t) cutoff functions -// ---------------------------------------------------------------------- - -/* ---------------------------------------------------------------------- - cutoff function Sprime - return cutoff and dX = derivative -------------------------------------------------------------------------- */ - -double PairAIREBO::Sp(double Xij, double Xmin, double Xmax, double &dX) -{ - double cutoff; - - double t = (Xij-Xmin) / (Xmax-Xmin); - if (t <= 0.0) { - cutoff = 1.0; - dX = 0.0; - } - else if (t >= 1.0) { - cutoff = 0.0; - dX = 0.0; - } - else { - cutoff = 0.5 * (1.0+cos(MY_PI*t)); - dX = (-MY_PI2*sin(MY_PI*t)) / (Xmax-Xmin); - } - return cutoff; -} - -/* ---------------------------------------------------------------------- - LJ cutoff function Sp2 - return cutoff and dX = derivative -------------------------------------------------------------------------- */ - -double PairAIREBO::Sp2(double Xij, double Xmin, double Xmax, double &dX) -{ - double cutoff; - - double t = (Xij-Xmin) / (Xmax-Xmin); - if (t <= 0.0) { - cutoff = 1.0; - dX = 0.0; - } - if (t >= 1.0) { - cutoff = 0.0; - dX = 0.0; - } - if (t>0.0 && t<1.0) { - cutoff = (1.0-(t*t*(3.0-2.0*t))); - dX = 6.0*(t*t-t) / (Xmax-Xmin); - } - return cutoff; -} - /* ---------------------------------------------------------------------- Bij function ------------------------------------------------------------------------- */ @@ -2123,11 +2070,6 @@ double PairAIREBO::bondorderLJ(int i, int j, double rij[3], double rijmag, NjiC = nC[atomj]-(wij*kronecker(itype,0)); NjiH = nH[atomj]-(wij*kronecker(itype,1)); - rij[0] = rij0[0]; - rij[1] = rij0[1]; - rij[2] = rij0[2]; - rijmag = rij0mag; - bij = 0.0; tmp = 0.0; tmp2 = 0.0; @@ -3133,7 +3075,7 @@ double PairAIREBO::PijSpline(double NijC, double NijH, int typei, int typej, if (typei == 0 && typej == 1){ if (NijC < pCHdom[0][0]) NijC=pCHdom[0][0]; if (NijC > pCHdom[0][1]) NijC=pCHdom[0][1]; - if (NijH < pCHdom[0][0]) NijH=pCHdom[1][0]; + if (NijH < pCHdom[1][0]) NijH=pCHdom[1][0]; if (NijH > pCHdom[1][1]) NijH=pCHdom[1][1]; if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) { @@ -3338,27 +3280,17 @@ double PairAIREBO::TijSpline(double Nij, double Nji, } /* ---------------------------------------------------------------------- - Kronecker delta function + add pages to REBO neighbor list ------------------------------------------------------------------------- */ -double PairAIREBO::kronecker(int a, int b) -{ - double kd; - if (a == b) kd = 1.0; - else kd = 0.0; - return kd; -} - -/* ---------------------------------------------------------------------- - add pages to REBO neighbor list, starting at npage -------------------------------------------------------------------------- */ - -void PairAIREBO::add_pages(int npage) +void PairAIREBO::add_pages() { + int toppage = maxpage; maxpage += PGDELTA; + pages = (int **) memory->srealloc(pages,maxpage*sizeof(int *),"AIREBO:pages"); - for (int i = npage; i < maxpage; i++) + for (int i = toppage; i < maxpage; i++) memory->create(pages[i],pgsize,"AIREBO:pages[i]"); } @@ -3954,17 +3886,23 @@ void PairAIREBO::read_file(char *filename) double PairAIREBO::Sp5th(double x, double coeffs[6], double *df) { - double f; - int i; - i = 0; - f = 0.0; - *df = 0.0; + double f, d; + const double x2 = x*x; + const double x3 = x2*x; - for (i = 0; i<6; i++) { - f += coeffs[i]*pow(x,((double) i)); - if (i > 0) *df += coeffs[i]*((double) i)*pow(x,((double) i-1.0)); - } + f = coeffs[0]; + f += coeffs[1]*x; + d = coeffs[1]; + f += coeffs[2]*x2; + d += 2.0*coeffs[2]*x; + f += coeffs[3]*x3; + d += 3.0*coeffs[3]*x2; + f += coeffs[4]*x2*x2; + d += 4.0*coeffs[4]*x3; + f += coeffs[5]*x2*x3; + d += 5.0*coeffs[5]*x2*x2; + *df = d; return f; } @@ -3975,25 +3913,28 @@ double PairAIREBO::Sp5th(double x, double coeffs[6], double *df) double PairAIREBO::Spbicubic(double x, double y, double coeffs[16], double df[2]) { - double f; - int i,j,cn; + double f,xn,yn,xn1,yn1,c; + int i,j; f = 0.0; df[0] = 0.0; df[1] = 0.0; - cn = 0; + xn = 1.0; for (i = 0; i < 4; i++) { + yn = 1.0; for (j = 0; j < 4; j++) { - f += coeffs[cn]*pow(x,((double) i))*pow(y,((double) j)); - if (i > 0) df[0] += - (coeffs[cn]*((double) i)*pow(x,((double) i-1.0)) * - pow(y,((double) j))); - if (j > 0) df[1] += - (coeffs[cn]*((double) j)*pow(x,((double) i)) * - pow(y,((double) j-1.0))); - cn++; + c = coeffs[i*4+j]; + + f += c*xn*yn; + if (i > 0) df[0] += c * ((double) i) * xn1 * yn; + if (j > 0) df[1] += c * ((double) j) * xn * yn1; + + yn1 = yn; + yn *= y; } + xn1 = xn; + xn *= x; } return f; @@ -4006,31 +3947,36 @@ double PairAIREBO::Spbicubic(double x, double y, double PairAIREBO::Sptricubic(double x, double y, double z, double coeffs[64], double df[3]) { - double f,ir,jr,kr; - int i,j,k,cn; + double f,ir,jr,kr,xn,yn,zn,xn1,yn1,zn1,c; + int i,j,k; f = 0.0; df[0] = 0.0; df[1] = 0.0; df[2] = 0.0; - cn = 0; + xn = 1.0; for (i = 0; i < 4; i++) { ir = (double) i; + yn = 1.0; for (j = 0; j < 4; j++) { jr = (double) j; + zn = 1.0; for (k = 0; k < 4; k++) { kr = (double) k; - f += (coeffs[cn]*pow(x,ir)*pow(y,jr)*pow(z,kr)); - if (i > 0) df[0] += - (coeffs[cn]*ir*pow(x,ir-1.0)*pow(y,jr)*pow(z,kr)); - if (j > 0) df[1] += - (coeffs[cn]*jr*pow(x,ir)*pow(y,jr-1.0)*pow(z,kr)); - if (k > 0) df[2] += - (coeffs[cn]*kr*pow(x,ir)*pow(y,jr)*pow(z,kr-1.0)); - cn++; + c = coeffs[16*i+4*j+k]; + f += c*xn*yn*zn; + if (i > 0) df[0] += c * ir * xn1 * yn * zn; + if (j > 0) df[1] += c * jr * xn * yn1 * zn; + if (k > 0) df[2] += c * kr * xn * yn * zn1; + zn1 = zn; + zn *= z; } + yn1 = yn; + yn *= y; } + xn1 = xn; + xn *= x; } return f; diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index 166e1ed4ed..0c4795ab0d 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -21,6 +21,8 @@ PairStyle(airebo,PairAIREBO) #define LMP_PAIR_AIREBO_H #include "pair.h" +#include "math.h" +#include "math_const.h" namespace LAMMPS_NS { @@ -28,7 +30,7 @@ class PairAIREBO : public Pair { public: PairAIREBO(class LAMMPS *); virtual ~PairAIREBO(); - void compute(int, int); + virtual void compute(int, int); virtual void settings(int, char **); void coeff(int, char **); void init_style(); @@ -36,15 +38,15 @@ class PairAIREBO : public Pair { double memory_usage(); protected: + int **pages; // neighbor list pages + int *map; // 0 (C), 1 (H), or -1 (NULL) for each type + int me; int ljflag,torflag; // 0/1 if LJ,torsion terms included int maxlocal; // size of numneigh, firstneigh arrays - int **pages; // neighbor list pages int maxpage; // # of pages currently allocated int pgsize; // size of neighbor page int oneatom; // max # of neighbors for one atom - int npage; // current page in page list - int *map; // 0 (C), 1 (H), or -1 (NULL) for each type double cutlj; // user-specified LJ cutoff double cutljrebosq; // cut for when to compute @@ -77,12 +79,12 @@ class PairAIREBO : public Pair { double PCCf[5][5],PCCdfdx[5][5],PCCdfdy[5][5],PCHf[5][5]; double PCHdfdx[5][5],PCHdfdy[5][5]; - double piCCf[5][5][10],piCCdfdx[5][5][10]; - double piCCdfdy[5][5][10],piCCdfdz[5][5][10]; - double piCHf[5][5][10],piCHdfdx[5][5][10]; - double piCHdfdy[5][5][10],piCHdfdz[5][5][10]; - double piHHf[5][5][10],piHHdfdx[5][5][10]; - double piHHdfdy[5][5][10],piHHdfdz[5][5][10]; + double piCCf[5][5][11],piCCdfdx[5][5][11]; + double piCCdfdy[5][5][11],piCCdfdz[5][5][11]; + double piCHf[5][5][11],piCHdfdx[5][5][11]; + double piCHdfdy[5][5][11],piCHdfdz[5][5][11]; + double piHHf[5][5][11],piHHdfdx[5][5][11]; + double piHHdfdy[5][5][11],piHHdfdz[5][5][11]; double Tf[5][5][10],Tdfdx[5][5][10],Tdfdy[5][5][10],Tdfdz[5][5][10]; void REBO_neigh(); @@ -94,17 +96,12 @@ class PairAIREBO : public Pair { double bondorderLJ(int, int, double *, double, double, double *, double, double **, int); - double Sp(double, double, double, double &); - double Sp2(double, double, double, double &); - double gSpline(double, double, int, double *, double *); double PijSpline(double, double, int, int, double *); double piRCSpline(double, double, double, int, int, double *); double TijSpline(double, double, double, double *); - double kronecker(int, int); - - void add_pages(int); + void add_pages(); void read_file(char *); double Sp5th(double, double *, double *); @@ -113,6 +110,63 @@ class PairAIREBO : public Pair { void spline_init(); void allocate(); + + // ---------------------------------------------------------------------- + // S'(t) and S(t) cutoff functions + // added to header for inlining + // ---------------------------------------------------------------------- + + /* ---------------------------------------------------------------------- + cutoff function Sprime + return cutoff and dX = derivative + no side effects + ------------------------------------------------------------------------- */ + + inline double Sp(double Xij, double Xmin, double Xmax, double &dX) const { + double cutoff; + + double t = (Xij-Xmin) / (Xmax-Xmin); + if (t <= 0.0) { + cutoff = 1.0; + dX = 0.0; + } else if (t >= 1.0) { + cutoff = 0.0; + dX = 0.0; + } else { + cutoff = 0.5 * (1.0+cos(t*MathConst::MY_PI)); + dX = (-0.5*MathConst::MY_PI*sin(t*MathConst::MY_PI)) / (Xmax-Xmin); + } + return cutoff; + }; + + /* ---------------------------------------------------------------------- + LJ cutoff function Sp2 + return cutoff and dX = derivative + no side effects + ------------------------------------------------------------------------- */ + + inline double Sp2(double Xij, double Xmin, double Xmax, double &dX) const { + double cutoff; + + double t = (Xij-Xmin) / (Xmax-Xmin); + if (t <= 0.0) { + cutoff = 1.0; + dX = 0.0; + } else if (t >= 1.0) { + cutoff = 0.0; + dX = 0.0; + } else { + cutoff = (1.0-(t*t*(3.0-2.0*t))); + dX = 6.0*(t*t-t) / (Xmax-Xmin); + } + return cutoff; + }; + + /* kronecker delta function returning a double */ + inline double kronecker(const int a, const int b) const { + return (a == b) ? 1.0 : 0.0; + }; + }; } From 8a24e16c9123ba6eb2e8f63e6586b935d9b71fb7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 16:21:15 +0000 Subject: [PATCH 244/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7197 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/MANYBODY/pair_comb.cpp | 24 +++++++++++++++--------- src/MANYBODY/pair_comb.h | 5 +++-- src/neigh_list.cpp | 6 +++--- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index a719d33b56..51bc45ad93 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -555,7 +555,7 @@ void PairComb::init_style() pgsize = neighbor->pgsize; oneatom = neighbor->oneatom; - if (maxpage == 0) add_pages(0); + if (maxpage == 0) add_pages(); } /* ---------------------------------------------------------------------- @@ -2077,10 +2077,12 @@ double PairComb::memory_usage() void PairComb::Short_neigh() { - int nj,npntj,*neighptrj,itype,jtype; - int iparam_ij,*ilist,*jlist,*numneigh,**firstneigh; + int nj,itype,jtype,iparam_ij; int inum,jnum,i,j,ii,jj; + int *neighptrj,*ilist,*jlist,*numneigh; + int **firstneigh; double xtmp,ytmp,ztmp,rr,rsq,delrj[3]; + double **x = atom->x; int *type = atom->type; int nlocal = atom->nlocal; @@ -2099,16 +2101,17 @@ void PairComb::Short_neigh() ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - npage = npntj = 0; + int npntj = 0; + int npage = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; itype = type[i]; - if(pgsize - npntj < oneatom) { + if (pgsize - npntj < oneatom) { npntj = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == maxpage) add_pages(); } nj = 0; @@ -2135,6 +2138,7 @@ void PairComb::Short_neigh() if (rsq > cutmin) continue; neighptrj[nj++] = j; } + sht_first[i] = neighptrj; sht_num[i] = nj; npntj += nj; @@ -2143,12 +2147,14 @@ void PairComb::Short_neigh() /* ---------------------------------------------------------------------- */ -void PairComb::add_pages(int npage) +void PairComb::add_pages() { + int toppage = maxpage; maxpage += PGDELTA; + pages = (int **) - memory->srealloc(pages,maxpage*sizeof(int *),"pair:pages"); - for (int i = npage; i < maxpage; i++) + memory->srealloc(pages,maxpage*sizeof(int *),"pair:pages"); + for (int i = toppage; i < maxpage; i++) memory->create(pages[i],pgsize,"pair:pages[i]"); } diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h index bda2805d56..0a8b11ad05 100644 --- a/src/MANYBODY/pair_comb.h +++ b/src/MANYBODY/pair_comb.h @@ -128,9 +128,10 @@ class PairComb : public Pair { void unpack_comm(int , int , double *); // Short range neighbor list - void add_pages(int ); + + void add_pages(); void Short_neigh(); - int npage, maxpage, pgsize, oneatom, **pages; + int maxpage, pgsize, oneatom, **pages; int *sht_num, **sht_first; // short-range neighbor list double cutmin; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 738bd5d7e1..13dc4a217f 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -183,18 +183,18 @@ void NeighList::stencil_allocate(int smax, int style) int **NeighList::add_pages() { - int npage = maxpage; + int toppage = maxpage; maxpage += PGDELTA; pages = (int **) memory->srealloc(pages,maxpage*sizeof(int *),"neighlist:pages"); - for (int i = npage; i < maxpage; i++) + for (int i = toppage; i < maxpage; i++) memory->create(pages[i],pgsize,"neighlist:pages[i]"); if (dnum) { dpages = (double **) memory->srealloc(dpages,maxpage*sizeof(double *),"neighlist:dpages"); - for (int i = npage; i < maxpage; i++) + for (int i = toppage; i < maxpage; i++) memory->create(dpages[i],dnum*pgsize,"neighlist:dpages[i]"); } From e62a6b19bf33261250c2d5672b6374772197b13c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 16:24:23 +0000 Subject: [PATCH 245/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7198 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- potentials/CH.airebo | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/potentials/CH.airebo b/potentials/CH.airebo index 0776baebb8..de6970b442 100644 --- a/potentials/CH.airebo +++ b/potentials/CH.airebo @@ -58,10 +58,10 @@ 0.32 bLJmin_HH 0.81 bLJmax_CC 0.9 bLJmax_CH -0.42 bLJmax_HH -0.0028437324 epsilon_CC -0.0020639767 epsilon_CH -0.0014994226 epsilon_HH +0.42 bLJmax_HH +0.002843732471143 epsilon_CC +0.002064935027177 epsilon_CH +0.001499422575693 epsilon_HH 3.4 sigma_CC 3.025 sigma_CH 2.65 sigma_HH From 667fde6a9e911177294a7ebfd65640d1aaaaebda Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 25 Oct 2011 16:24:28 +0000 Subject: [PATCH 246/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7199 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 4e6050f3a0..0e3e8cc989 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "24 Oct 2011" +#define LAMMPS_VERSION "25 Oct 2011"

  • tx1HY6QOxbbO8pfARrMj2_loX3>S;44 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Π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�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⁣z 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⁣*@(1y3 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

    t2w7gzXgpf7~2w1a~R#-Jz1 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�scOVege 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

    wSihme`QB6Af4{b>>9q(p4F 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�Mi&4$M>9(~Wpkcw_D@*hOve@4SZlU6bFkz$cxR!NXm;W;J4unr zl;UL!v!{p8`?JS?W?3;hsCNZjZl?F^)A#`Ff-mPsf&on(oc}6m!CATf3$cld<$oLi zSvWa>Odnqr?Uy<}J}{-}3+`@3dB5m3-cmp$`kS)zbmsrJ5!TVNx3cL{ECh z3%GXXTuBA++k|fw{88!FMW9Vqi%t(@y*(JuAnw+sJHh~9+^r{UY^bQ~uT3}{+dtcX z2wmD=UU`KB8jGU&G`su;0Ey6>)eQCm8`H+Z

    -`3GQaZ0S#dY|<|&l9{h4z{?i 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�`WS2V1`Ckpj4QADi`Z;OSx$3DM_P3ABd_ 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

    H@FmJR%RIWtY6yL%PJO) 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�CV>7RoGUwId?W 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�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

  • 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 G5B+~gaW1p~ From b3942f9b2984c13807111bd94d80a2c170fcaf90 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 20:29:58 +0000 Subject: [PATCH 089/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6892 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_wall_piston.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SHOCK/fix_wall_piston.cpp b/src/SHOCK/fix_wall_piston.cpp index 9dd6325bb4..e639b62858 100644 --- a/src/SHOCK/fix_wall_piston.cpp +++ b/src/SHOCK/fix_wall_piston.cpp @@ -255,10 +255,12 @@ void FixWallPiston::post_integrate() if (update->ntimestep % 1000 == 0) if (comm->me == 0) { if (screen) - fprintf(screen,"SHOCK: step %d t %g zpos %g vz %g az %g zlo %g\n", + fprintf(screen,"SHOCK: step " BIGINT_FORMAT + " t %g zpos %g vz %g az %g zlo %g\n", update->ntimestep, t, zlo, vz, paccelz, domain->boxlo[2]); if (logfile) - fprintf(logfile,"SHOCK: step %d t %g zpos %g vz %g az %g zlo %g\n", + fprintf(logfile,"SHOCK: step " BIGINT_FORMAT + " t %g zpos %g vz %g az %g zlo %g\n", update->ntimestep, t, zlo, vz, paccelz, domain->boxlo[2]); } From e196809f376e70b99938038d964543c1ecfa5dca Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 21:19:49 +0000 Subject: [PATCH 090/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6894 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/COLLOID/pair_yukawa_colloid.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/COLLOID/pair_yukawa_colloid.cpp b/src/COLLOID/pair_yukawa_colloid.cpp index 5df2ba8b78..10ef116386 100644 --- a/src/COLLOID/pair_yukawa_colloid.cpp +++ b/src/COLLOID/pair_yukawa_colloid.cpp @@ -38,11 +38,11 @@ PairYukawaColloid::PairYukawaColloid(LAMMPS *lmp) : PairYukawa(lmp) {} void PairYukawaColloid::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair,radi,radj; - double rsq,r2inv,r,rinv,screening,forceyukawa,factor_coul; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,radi,radj; + double rsq,r2inv,r,rinv,screening,forceyukawa,factor; int *ilist,*jlist,*numneigh,**firstneigh; - ecoul = 0.0; + evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -51,7 +51,7 @@ void PairYukawaColloid::compute(int eflag, int vflag) double *radius = atom->radius; int *type = atom->type; int nlocal = atom->nlocal; - double *special_coul = force->special_coul; + double *special_lj = force->special_lj; int newton_pair = force->newton_pair; inum = list->inum; @@ -73,7 +73,7 @@ void PairYukawaColloid::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; - factor_coul = special_coul[sbmask(j)]; + factor = special_lj[sbmask(j)]; j &= NEIGHMASK; delx = xtmp - x[j][0]; @@ -90,7 +90,7 @@ void PairYukawaColloid::compute(int eflag, int vflag) screening = exp(-kappa*(r-(radi+radj))); forceyukawa = a[itype][jtype] * screening; - fpair = factor_coul*forceyukawa * rinv; + fpair = factor*forceyukawa * rinv; f[i][0] += delx*fpair; f[i][1] += dely*fpair; @@ -102,12 +102,12 @@ void PairYukawaColloid::compute(int eflag, int vflag) } if (eflag) { - ecoul = a[itype][jtype]/kappa * screening - offset[itype][jtype]; - ecoul *= factor_coul; + evdwl = a[itype][jtype]/kappa * screening - offset[itype][jtype]; + evdwl *= factor; } if (evflag) ev_tally(i,j,nlocal,newton_pair, - 0.0,ecoul,fpair,delx,dely,delz); + evdwl,0.0,fpair,delx,dely,delz); } } } @@ -170,8 +170,8 @@ double PairYukawaColloid::single(int i, int j, int itype, int jtype, rinv = 1.0/r; screening = exp(-kappa*(r-(rad[itype]+rad[jtype]))); forceyukawa = a[itype][jtype] * screening; - fforce = factor_coul*forceyukawa * rinv; + fforce = factor_lj*forceyukawa * rinv; phi = a[itype][jtype]/kappa * screening - offset[itype][jtype]; - return factor_coul*phi; + return factor_lj*phi; } From b0ffe469237891772e7a7090f2c59cf9ec9a9efd Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 21:21:28 +0000 Subject: [PATCH 091/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6895 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_append_atoms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp index 0bb38b48a6..8036c27248 100644 --- a/src/SHOCK/fix_append_atoms.cpp +++ b/src/SHOCK/fix_append_atoms.cpp @@ -91,7 +91,7 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : if (domain->boundary[2][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"freq") == 0) { if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); - freq = atof(arg[iarg+1]); + freq = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"spatial") == 0) { if (iarg+3 > narg) error->all("Illegal fix append_atoms command"); @@ -251,7 +251,7 @@ int FixAppendAtoms::get_spatial() double binsize = 2.0; double min_energy=0.0; double max_energy=0.0; - int header = size / binsize; + int header = static_cast (size / binsize); advance = 0; for (int loop=1; loop <= header; loop++) { From be4f74041f608f11b4d55b88b36ed497a4a877ff Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 21:56:42 +0000 Subject: [PATCH 092/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6897 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_evaporate.cpp | 64 +++++++++++++++++++++++++++++++++++++++---- src/fix_rigid.cpp | 10 +++---- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/fix_evaporate.cpp b/src/fix_evaporate.cpp index c5db3dca4c..49a19e7c8d 100644 --- a/src/fix_evaporate.cpp +++ b/src/fix_evaporate.cpp @@ -21,6 +21,7 @@ #include "domain.h" #include "region.h" #include "comm.h" +#include "force.h" #include "group.h" #include "random_park.h" #include "random_mars.h" @@ -162,7 +163,8 @@ void FixEvaporate::init() void FixEvaporate::pre_exchange() { - int i,iwhichglobal,iwhichlocal; + int i,j,m,iwhichglobal,iwhichlocal; + int ndel,ndeltopo[4]; if (update->ntimestep != next_reneighbor) return; @@ -197,9 +199,10 @@ void FixEvaporate::pre_exchange() nbefore -= ncount; // ndel = total # of atom deletions, in or out of region + // ndeltopo[1,2,3,4] = ditto for bonds, angles, dihedrals, impropers // mark[] = 1 if deleted - int ndel = 0; + ndel = 0; for (i = 0; i < nlocal; i++) mark[i] = 0; // atomic deletions @@ -226,12 +229,14 @@ void FixEvaporate::pre_exchange() // bcast mol ID and delete all atoms in that molecule on any proc // update deletion count by total # of atoms in molecule // shrink list of eligible candidates as any of my atoms get marked - // keep ndel,ncount,nall,nbefore current after each molecule deletion + // keep ndel,ndeltopo,ncount,nall,nbefore current after each mol deletion } else { int me,proc,iatom,imolecule,ndelone,ndelall; int *molecule = atom->molecule; + ndeltopo[0] = ndeltopo[1] = ndeltopo[2] = ndeltopo[3] = 0; + while (nall && ndel < nflux) { // pick an iatom,imolecule on proc me to delete @@ -245,7 +250,8 @@ void FixEvaporate::pre_exchange() } else me = -1; // bcast mol ID to delete all atoms from - // delete single iatom if mol ID = 0 + // if mol ID > 0, delete any atom in molecule and decrement counters + // if mol ID == 0, delete single iatom MPI_Allreduce(&me,&proc,1,MPI_INT,MPI_MAX,world); MPI_Bcast(&imolecule,1,MPI_INT,proc,world); @@ -254,6 +260,44 @@ void FixEvaporate::pre_exchange() if (imolecule && molecule[i] == imolecule) { mark[i] = 1; ndelone++; + + if (atom->avec->bonds_allow) { + if (force->newton_bond) ndeltopo[0] += atom->num_bond[i]; + else { + for (j = 0; j < atom->num_bond[i]; j++) { + m = atom->map(atom->bond_atom[i][j]); + if (m >= 0 && m < nlocal) ndeltopo[0]++; + } + } + } + if (atom->avec->angles_allow) { + if (force->newton_bond) ndeltopo[1] += atom->num_angle[i]; + else { + for (j = 0; j < atom->num_angle[i]; j++) { + m = atom->map(atom->angle_atom2[i][j]); + if (m >= 0 && m < nlocal) ndeltopo[1]++; + } + } + } + if (atom->avec->dihedrals_allow) { + if (force->newton_bond) ndeltopo[2] += atom->num_dihedral[i]; + else { + for (j = 0; j < atom->num_dihedral[i]; j++) { + m = atom->map(atom->dihedral_atom2[i][j]); + if (m >= 0 && m < nlocal) ndeltopo[2]++; + } + } + } + if (atom->avec->impropers_allow) { + if (force->newton_bond) ndeltopo[3] += atom->num_improper[i]; + else { + for (j = 0; j < atom->num_improper[i]; j++) { + m = atom->map(atom->improper_atom2[i][j]); + if (m >= 0 && m < nlocal) ndeltopo[3]++; + } + } + } + } else if (me == proc && i == iatom) { mark[i] = 1; ndelone++; @@ -273,7 +317,6 @@ void FixEvaporate::pre_exchange() // update ndel,ncount,nall,nbefore MPI_Allreduce(&ndelone,&ndelall,1,MPI_INT,MPI_SUM,world); - ndel += ndelall; MPI_Allreduce(&ncount,&nall,1,MPI_INT,MPI_SUM,world); MPI_Scan(&ncount,&nbefore,1,MPI_INT,MPI_SUM,world); nbefore -= ncount; @@ -292,11 +335,20 @@ void FixEvaporate::pre_exchange() } } - // reset global natoms + // reset global natoms and bonds, angles, etc // if global map exists, reset it now instead of waiting for comm // since deleting atoms messes up ghosts atom->natoms -= ndel; + if (molflag) { + int all[4]; + MPI_Allreduce(ndeltopo,all,4,MPI_INT,MPI_SUM,world); + atom->nbonds -= all[0]; + atom->nangles -= all[1]; + atom->ndihedrals -= all[2]; + atom->nimpropers -= all[3]; + } + if (ndel && atom->map_style) { atom->nghost = 0; atom->map_init(); diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp index 85e29292d7..b2b79a5af7 100644 --- a/src/fix_rigid.cpp +++ b/src/fix_rigid.cpp @@ -1910,14 +1910,14 @@ int FixRigid::unpack_exchange(int nlocal, double *buf) eflags[nlocal] = static_cast (buf[m++]); if (dorientflag) { dorient[nlocal][0] = buf[m++]; - dorient[nlocal][0] = buf[m++]; - dorient[nlocal][0] = buf[m++]; + dorient[nlocal][1] = buf[m++]; + dorient[nlocal][2] = buf[m++]; } if (qorientflag) { qorient[nlocal][0] = buf[m++]; - qorient[nlocal][0] = buf[m++]; - qorient[nlocal][0] = buf[m++]; - qorient[nlocal][0] = buf[m++]; + qorient[nlocal][1] = buf[m++]; + qorient[nlocal][2] = buf[m++]; + qorient[nlocal][3] = buf[m++]; } return m; } From a434d6fd001a3454c6c015a13dcd7d4b54dcad3b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 31 Aug 2011 22:59:20 +0000 Subject: [PATCH 093/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6901 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SRD/fix_srd.cpp | 53 +++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index d46c58d434..1516e23d51 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -19,6 +19,7 @@ #include "string.h" #include "stdlib.h" #include "fix_srd.h" +#include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" #include "group.h" @@ -356,7 +357,10 @@ void FixSRD::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]; - if (vsq > vmaxsq) nrescale++; + if (vsq > vmaxsq) { + nrescale++; + MathExtra::scale3(vmax/sqrt(vsq),v[i]); + } } int all; @@ -944,7 +948,10 @@ void FixSRD::reset_velocities() for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]; - if (vsq > vmaxsq) nrescale++; + if (vsq > vmaxsq) { + nrescale++; + MathExtra::scale3(vmax/sqrt(vsq),v[i]); + } } } @@ -1174,7 +1181,10 @@ void FixSRD::collisions_single() double vsq = vsnew[0]*vsnew[0] + vsnew[1]*vsnew[1] + vsnew[2]*vsnew[2]; - if (vsq > vmaxsq) nrescale++; + if (vsq > vmaxsq) { + nrescale++; + MathExtra::scale3(vmax/sqrt(vsq),vsnew); + } // update BIG particle and WALL and SRD // BIG particle is not torqued if sphere and SLIP collision @@ -1340,7 +1350,10 @@ void FixSRD::collisions_multi() // check on rescaling of vsnew double vsq = vsnew[0]*vsnew[0] + vsnew[1]*vsnew[1] + vsnew[2]*vsnew[2]; - if (vsq > vmaxsq) nrescale++; + if (vsq > vmaxsq) { + nrescale++; + MathExtra::scale3(vmax/sqrt(vsq),vsnew); + } // update BIG particle and WALL and SRD // BIG particle is not torqued if sphere and SLIP collision @@ -2145,10 +2158,8 @@ void FixSRD::parameterize() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { if (rmass) { - if (mass_srd == 0.0) { - mass_srd = rmass[i]; - printf("MASS SRD %g\n",rmass[i]); - } else if (rmass[i] != mass_srd) flag = 1; + if (mass_srd == 0.0) mass_srd = rmass[i]; + else if (rmass[i] != mass_srd) flag = 1; } else { if (mass_srd == 0.0) mass_srd = mass[type[i]]; else if (mass[type[i]] != mass_srd) flag = 1; @@ -2387,8 +2398,6 @@ void FixSRD::parameterize() error->warning("Fix srd viscosity < 0.0 due to low SRD density"); if (bigexist && dt_big*vmax > minbigdiam && me == 0) error->warning("Fix srd particles may move > big particle diameter"); - if (wallexist && collidestyle == NOSLIP && shiftflag == 1) - error->warning("Fix srd no-slip wall collisions with bin shifting"); } /* ---------------------------------------------------------------------- @@ -2812,9 +2821,11 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic) first->nsend = second->nrecv = 0; if ((myloc[0]+1)*nbin1x % procgrid[0] == 0) second->nsend = first->nrecv = 0; - } else if (dynamic == 0 && domain->xperiodic == 0) { - if (myloc[0] == 0) first->nsend = second->nrecv = 0; - if (myloc[0] == procgrid[0]-1) second->nsend = first->nrecv = 0; + } else { + if (domain->xperiodic == 0) { + if (myloc[0] == 0) first->nsend = second->nrecv = 0; + if (myloc[0] == procgrid[0]-1) second->nsend = first->nrecv = 0; + } } if (reallocflag) { @@ -2854,9 +2865,11 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic) first->nsend = second->nrecv = 0; if ((myloc[1]+1)*nbin1y % procgrid[1] == 0) second->nsend = first->nrecv = 0; - } else if (dynamic == 0 && domain->yperiodic == 0) { - if (myloc[1] == 0) first->nsend = second->nrecv = 0; - if (myloc[1] == procgrid[1]-1) second->nsend = first->nrecv = 0; + } else { + if (domain->yperiodic == 0) { + if (myloc[1] == 0) first->nsend = second->nrecv = 0; + if (myloc[1] == procgrid[1]-1) second->nsend = first->nrecv = 0; + } } if (reallocflag) { @@ -2897,9 +2910,11 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic) first->nsend = second->nrecv = 0; if ((myloc[2]+1)*nbin1z % procgrid[2] == 0) second->nsend = first->nrecv = 0; - } else if (dynamic == 0 && domain->zperiodic == 0) { - if (myloc[2] == 0) first->nsend = second->nrecv = 0; - if (myloc[2] == procgrid[2]-1) second->nsend = first->nrecv = 0; + } else { + if (domain->zperiodic == 0) { + if (myloc[2] == 0) first->nsend = second->nrecv = 0; + if (myloc[2] == procgrid[2]-1) second->nsend = first->nrecv = 0; + } } if (reallocflag) { From d43381d50cea9781047a43f4cf24613eebff5120 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 1 Sep 2011 14:51:33 +0000 Subject: [PATCH 094/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6904 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_history.html | 70 +++++++-------- doc/Section_history.txt | 70 +++++++-------- doc/Section_intro.html | 184 +++++++++---------------------------- doc/Section_intro.txt | 190 +++++++++------------------------------ 4 files changed, 146 insertions(+), 368 deletions(-) diff --git a/doc/Section_history.html b/doc/Section_history.html index e84bb721ed..522e4e1220 100644 --- a/doc/Section_history.html +++ b/doc/Section_history.html @@ -24,56 +24,46 @@ molecular dynamics codes I've distributed. -

    The current version of LAMMPS incorporates nearly all the features -from previous parallel MD codes developed at Sandia. These include -earlier versions of LAMMPS itself, Warp and ParaDyn for metals, and -GranFlow for granular materials. +

    The Wish list link on the +LAMMPS WWW page gives a list of features we are hoping to add to +LAMMPS in the future, including contact names of individuals you can +email if you are interested in contributing to the developement or +would be a future user of that feature.

    -

    These are new features we'd like to eventually add to LAMMPS. Some -are being worked on; some haven't been implemented because of lack of -time or interest; others are just a lot of work! See this -page on the LAMMPS WWW site for more details. +

    You can also send email to the +developers if you want to add +your wish to the list.

    - - -
    • Coupling to finite elements for streess-strain -
    • New ReaxFF implementation -
    • Nudged elastic band -
    • Temperature accelerated dynamics -
    • Triangulated particles -
    • Stochastic rotation dynamics -
    • Stokesian dynamics via fast lubrication dynamics -
    • Long-range point-dipole solver -
    • Per-atom energy and stress for long-range Coulombics -
    • Long-range Coulombics via Ewald and PPPM for triclinic boxes -
    • Metadynamics -
    • Direct Simulation Monte Carlo - DSMC -

    13.2 Past versions

    LAMMPS development began in the mid 1990s under a cooperative research & development agreement (CRADA) between two DOE labs (Sandia and LLNL) -and 3 companies (Cray, Bristol Myers Squibb, and Dupont). Soon after -the CRADA ended, a final F77 version of the code, LAMMPS 99, was -released. As development of LAMMPS continued at Sandia, the memory -management in the code was converted to F90; a final F90 version was -released as LAMMPS 2001. +and 3 companies (Cray, Bristol Myers Squibb, and Dupont). The goal was +to develop a large-scale parallel classical MD code; the coding effort +was led by Steve Plimpton at Sandia. +

    +

    After the CRADA ended, a final F77 version, LAMMPS 99, was +released. As development of LAMMPS continued at Sandia, its memory +management was converted to F90; a final F90 version was released as +LAMMPS 2001.

    The current LAMMPS is a rewrite in C++ and was first publicly released -in 2004. It includes many new features, including features from other -parallel molecular dynamics codes written at Sandia, namely ParaDyn, -Warp, and GranFlow. ParaDyn is a parallel implementation of the -popular serial DYNAMO code developed by Stephen Foiles and Murray Daw -for their embedded atom method (EAM) metal potentials. ParaDyn uses -atom- and force-decomposition algorithms to run in parallel. Warp is -also a parallel implementation of the EAM potentials designed for -large problems, with boundary conditions specific to shearing solids -in varying geometries. GranFlow is a granular materials code with -potentials and boundary conditions peculiar to granular systems. All -of these codes (except ParaDyn) use spatial-decomposition techniques -for their parallelism. +as an open source code in 2004. It includes many new features beyond +those in LAMMPS 99 or 2001. It also includes features from older +parallel MD codes written at Sandia, namely ParaDyn, Warp, and +GranFlow (see below). +

    +

    In late 2006 we began merging new capabilities into LAMMPS that were +developed by Aidan Thompson at Sandia for his MD code GRASP, which has +a parallel framework similar to LAMMPS. Most notably, these have +included many-body potentials - Stillinger-Weber, Tersoff, ReaxFF - +and the associated charge-equilibration routines needed for ReaxFF. +

    +

    The History link on the +LAMMPS WWW page gives a timeline of features added to the +C++ open-source version of LAMMPS over the last several years.

    These older codes are available for download from the LAMMPS WWW site, except for Warp & GranFlow which were primarily used diff --git a/doc/Section_history.txt b/doc/Section_history.txt index de84ffb2bf..92600b7e22 100644 --- a/doc/Section_history.txt +++ b/doc/Section_history.txt @@ -21,30 +21,15 @@ molecular dynamics codes I've distributed. 13.1 Coming attractions :h4,link(hist_1) -The current version of LAMMPS incorporates nearly all the features -from previous parallel MD codes developed at Sandia. These include -earlier versions of LAMMPS itself, Warp and ParaDyn for metals, and -GranFlow for granular materials. +The "Wish list link"_http://lammps.sandia.gov/future.html on the +LAMMPS WWW page gives a list of features we are hoping to add to +LAMMPS in the future, including contact names of individuals you can +email if you are interested in contributing to the developement or +would be a future user of that feature. -These are new features we'd like to eventually add to LAMMPS. Some -are being worked on; some haven't been implemented because of lack of -time or interest; others are just a lot of work! See "this -page"_lwsfuture on the LAMMPS WWW site for more details. - -:link(lwsfuture,http://lammps.sandia.gov/future.html) - -Coupling to finite elements for streess-strain -New ReaxFF implementation -Nudged elastic band -Temperature accelerated dynamics -Triangulated particles -Stochastic rotation dynamics -Stokesian dynamics via fast lubrication dynamics -Long-range point-dipole solver -Per-atom energy and stress for long-range Coulombics -Long-range Coulombics via Ewald and PPPM for triclinic boxes -Metadynamics -Direct Simulation Monte Carlo - DSMC :ul +You can also send "email to the +developers"_http://lammps.sandia.gov/authors.html if you want to add +your wish to the list. :line @@ -52,25 +37,30 @@ Direct Simulation Monte Carlo - DSMC :ul LAMMPS development began in the mid 1990s under a cooperative research & development agreement (CRADA) between two DOE labs (Sandia and LLNL) -and 3 companies (Cray, Bristol Myers Squibb, and Dupont). Soon after -the CRADA ended, a final F77 version of the code, LAMMPS 99, was -released. As development of LAMMPS continued at Sandia, the memory -management in the code was converted to F90; a final F90 version was -released as LAMMPS 2001. +and 3 companies (Cray, Bristol Myers Squibb, and Dupont). The goal was +to develop a large-scale parallel classical MD code; the coding effort +was led by Steve Plimpton at Sandia. + +After the CRADA ended, a final F77 version, LAMMPS 99, was +released. As development of LAMMPS continued at Sandia, its memory +management was converted to F90; a final F90 version was released as +LAMMPS 2001. The current LAMMPS is a rewrite in C++ and was first publicly released -in 2004. It includes many new features, including features from other -parallel molecular dynamics codes written at Sandia, namely ParaDyn, -Warp, and GranFlow. ParaDyn is a parallel implementation of the -popular serial DYNAMO code developed by Stephen Foiles and Murray Daw -for their embedded atom method (EAM) metal potentials. ParaDyn uses -atom- and force-decomposition algorithms to run in parallel. Warp is -also a parallel implementation of the EAM potentials designed for -large problems, with boundary conditions specific to shearing solids -in varying geometries. GranFlow is a granular materials code with -potentials and boundary conditions peculiar to granular systems. All -of these codes (except ParaDyn) use spatial-decomposition techniques -for their parallelism. +as an open source code in 2004. It includes many new features beyond +those in LAMMPS 99 or 2001. It also includes features from older +parallel MD codes written at Sandia, namely ParaDyn, Warp, and +GranFlow (see below). + +In late 2006 we began merging new capabilities into LAMMPS that were +developed by Aidan Thompson at Sandia for his MD code GRASP, which has +a parallel framework similar to LAMMPS. Most notably, these have +included many-body potentials - Stillinger-Weber, Tersoff, ReaxFF - +and the associated charge-equilibration routines needed for ReaxFF. + +The "History link"_http://lammps.sandia.gov/history.html on the +LAMMPS WWW page gives a timeline of features added to the +C++ open-source version of LAMMPS over the last several years. These older codes are available for download from the "LAMMPS WWW site"_lws, except for Warp & GranFlow which were primarily used diff --git a/doc/Section_intro.html b/doc/Section_intro.html index b77261945d..afc3c5d040 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -477,154 +477,58 @@ Hierarchical Modeling". -

    The following papers describe the parallel algorithms used in LAMMPS. +

    The following paper describe the basic parallel algorithms used in +LAMMPS. If you use LAMMPS results in your published work, please cite +this paper and include a pointer to the LAMMPS WWW Site +(http://lammps.sandia.gov):

    S. J. Plimpton, Fast Parallel Algorithms for Short-Range Molecular Dynamics, J Comp Phys, 117, 1-19 (1995).

    -

    S. J. Plimpton, R. Pollock, M. Stevens, Particle-Mesh Ewald and -rRESPA for Parallel Molecular Dynamics Simulations, in Proc of the -Eighth SIAM Conference on Parallel Processing for Scientific -Computing, Minneapolis, MN (March 1997). +

    Other papers describing specific algorithms used in LAMMPS are listed +under the Citing LAMMPS link of +the LAMMPS WWW page.

    -

    If you use LAMMPS results in your published work, please cite the J -Comp Phys reference and include a pointer to the LAMMPS WWW Site -(http://lammps.sandia.gov). +

    The Publications link on the +LAMMPS WWW page lists papers that have cited LAMMPS. If your paper is +not listed there for some reason, feel free to send us the info. If +the simulations in your paper produced cool pictures or animations, +we'll be pleased to add them to the +Pictures or +Movies pages of the LAMMPS WWW +site.

    -

    If you send is information about your publication, we'll be pleased to -add it to the Publications page of the LAMMPS WWW Site. Ditto -for a picture or movie for the Pictures or Movies pages. +

    The core group of LAMMPS developers is at Sandia National Labs:

    -

    The core group of LAMMPS developers is at Sandia National Labs. They -include Steve Plimpton, Paul Crozier, and Aidan Thompson and can -be contacted via email: sjplimp, pscrozi, athomps at sandia.gov. +

    • Steve Plimpton, sjplimp at sandia.gov +
    • Aidan Thompson, athomps at sandia.gov +
    • Paul Crozier, pscrozi at sandia.gov +
    +

    The following folks are responsible for significant contributions to +the code, or other aspects of the LAMMPS development effort. Many of +the packages they have written are somewhat unique to LAMMPS and the +code would not be as general-purpose as it is without their expertise +and efforts.

    -

    Here are various folks who have made significant contributions to -features in LAMMPS. The most recent contributions are at the top of -the list. -

    - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    pppm GPU single and double Mike Brown (ORNL)
    pair_style lj/cut/expand Inderaj Bains (NVIDIA)
    temperature accelerated dynamics (TAD) Aidan Thompson (Sandia)
    pair reax/c and fix qeq/reax Metin Aktulga (Purdue, now LBNL)
    DREIDING force field, pair_style hbond/dreiding, etc Tod Pascal (CalTech)
    fix adapt and compute ti for thermodynamic integreation for free energies Sai Jayaraman (Sandia)
    pair born and pair gauss Sai Jayaraman (Sandia)
    stochastic rotation dynamics (SRD) via fix srd Jemery Lechman (Sandia) and Pieter in 't Veld (BASF)
    ipp Perl script tool Reese Jones (Sandia)
    eam_database and createatoms tools Xiaowang Zhou (Sandia)
    electron force field (eFF) Andres Jaramillo-Botero and Julius Su (Caltech)
    embedded ion method (EIM) potential Xiaowang Zhou (Sandia)
    COMB potential with charge equilibration Tzu-Ray Shan (U Florida)
    fix ave/correlate Benoit Leblanc, Dave Rigby, Paul Saxe (Materials Design) and Reese Jones (Sandia)
    pair_style peri/lps Mike Parks (Sandia)
    fix msst Lawrence Fried (LLNL), Evan Reed (LLNL, Stanford)
    thermo_style custom tpcpu & spcpu keywords Axel Kohlmeyer (Temple U)
    fix rigid/nve, fix rigid/nvt Tony Sheh and Trung Dac Nguyen (U Michigan)
    public SVN & Git repositories for LAMMPS Axel Kohlmeyer (Temple U) and Bill Goldman (Sandia)
    fix nvt, fix nph, fix npt, Parinello/Rahman dynamics, fix box/relax Aidan Thompson (Sandia)
    compute heat/flux German Samolyuk (ORNL) and Mario Pinto (Computational Research Lab, Pune, India)
    pair yukawa/colloid Randy Schunk (Sandia)
    fix wall/colloid Jeremy Lechman (Sandia)
    pair_style dsmc for Direct Simulation Monte Carlo (DSMC) modeling Paul Crozier (Sandia)
    fix imd for real-time viz and interactive MD Axel Kohlmeyer (Temple Univ)
    concentration-dependent EAM potential Alexander Stukowski (Technical University of Darmstadt)
    parallel replica dymamics (PRD) Mike Brown (Sandia)
    min_style hftn Todd Plantenga (Sandia)
    fix atc Reese Jones, Jon Zimmerman, Jeremy Templeton (Sandia)
    dump cfg Liang Wan (Chinese Academy of Sciences)
    fix nvt with Nose/Hoover chains Andy Ballard (U Maryland)
    pair_style lj/cut/gpu, pair_style gayberne/gpu Mike Brown (Sandia)
    pair_style lj96/cut, bond_style table, angle_style table Chuanfu Luo
    fix langevin tally Carolyn Phillips (U Michigan)
    compute heat/flux for Green-Kubo Reese Jones (Sandia), Philip Howell (Siemens), Vikas Varsney (AFRL)
    region cone Pim Schravendijk
    fix reax/bonds Aidan Thompson (Sandia)
    pair born/coul/long Ahmed Ismail (Sandia)
    fix ttm Paul Crozier (Sandia) and Carolyn Phillips (U Michigan)
    fix box/relax Aidan Thompson and David Olmsted (Sandia)
    ReaxFF potential Aidan Thompson (Sandia) and Hansohl Cho (MIT)
    compute cna/atom Wan Liang (Chinese Academy of Sciences)
    Tersoff/ZBL potential Dave Farrell (Northwestern U)
    peridynamics Mike Parks (Sandia)
    fix smd for steered MD Axel Kohlmeyer (U Penn)
    GROMACS pair potentials Mark Stevens (Sandia)
    lmp2vmd tool Axel Kohlmeyer (U Penn)
    compute group/group Naveen Michaud-Agrawal (Johns Hopkins U)
    USER-CG-CMM package for coarse-graining Axel Kohlmeyer (U Penn)
    cosine/delta angle potential Axel Kohlmeyer (U Penn)
    VIM editor add-ons for LAMMPS input scripts Gerolf Ziegenhain
    pair lubricate Randy Schunk (Sandia)
    compute ackland/atom Gerolf Zeigenhain
    kspace_style ewald/n, pair_style lj/coul, pair_style buck/coul Pieter in 't Veld (Sandia)
    AIREBO bond-order potential Ase Henry (MIT)
    making LAMMPS a true "object" that can be instantiated multiple times, e.g. as a library Ben FrantzDale (RPI)
    pymol_asphere viz tool Mike Brown (Sandia)
    NEMD SLLOD integration Pieter in 't Veld (Sandia)
    tensile and shear deformations Pieter in 't Veld (Sandia)
    GayBerne potential Mike Brown (Sandia)
    ellipsoidal particles Mike Brown (Sandia)
    colloid potentials Pieter in 't Veld (Sandia)
    fix heat Paul Crozier and Ed Webb (Sandia)
    neighbor multi and communicate multi Pieter in 't Veld (Sandia)
    MATLAB post-processing scripts Arun Subramaniyan (Purdue)
    triclinic (non-orthogonal) simulation domains Pieter in 't Veld (Sandia)
    thermo_extract tool Vikas Varshney (Wright Patterson AFB)
    fix ave/time and fix ave/spatial Pieter in 't Veld (Sandia)
    MEAM potential Greg Wagner (Sandia)
    optimized pair potentials for lj/cut, charmm/long, eam, morse James Fischer (High Performance Technologies), David Richie and Vincent Natoli (Stone Ridge Technologies)
    fix wall/lj126 Mark Stevens (Sandia)
    Stillinger-Weber and Tersoff potentials Aidan Thompson and Xiaowang Zhou (Sandia)
    region prism Pieter in 't Veld (Sandia)
    LJ tail corrections for energy/pressure Paul Crozier (Sandia)
    fix momentum and recenter Naveen Michaud-Agrawal (Johns Hopkins U)
    multi-letter variable names Naveen Michaud-Agrawal (Johns Hopkins U)
    OPLS dihedral potential Mark Stevens (Sandia)
    POEMS coupled rigid body integrator Rudranarayan Mukherjee (RPI)
    faster pair hybrid potential James Fischer (High Performance Technologies, Inc), Vincent Natoli and David Richie (Stone Ridge Technology)
    breakable bond quartic potential Chris Lorenz and Mark Stevens (Sandia)
    DCD and XTC dump styles Naveen Michaud-Agrawal (Johns Hopkins U)
    grain boundary orientation fix Koenraad Janssens and David Olmsted (Sandia)
    lj/smooth pair potential Craig Maloney (UCSB)
    radius-of-gyration spring fix Naveen Michaud-Agrawal (Johns Hopkins U) and Paul Crozier (Sandia)
    self spring fix Naveen Michaud-Agrawal (Johns Hopkins U)
    EAM CoAl and AlCu potentials Kwang-Reoul Lee (KIST, Korea)
    cosine/squared angle potential Naveen Michaud-Agrawal (Johns Hopkins U)
    helix dihedral potential Naveen Michaud-Agrawal (Johns Hopkins U) and Mark Stevens (Sandia)
    Finnis/Sinclair EAM Tim Lau (MIT)
    dissipative particle dynamics (DPD) potentials Kurt Smith (U Pitt) and Frank van Swol (Sandia)
    TIP4P potential (4-site water) Ahmed Ismail and Amalie Frischknecht (Sandia)
    uniaxial strain fix Carsten Svaneborg (Max Planck Institute)
    thermodynamics enhanced by fix quantities Aidan Thompson (Sandia)
    compressed dump files Erik Luijten (U Illinois)
    cylindrical indenter fix Ravi Agrawal (Northwestern U)
    electric field fix Christina Payne (Vanderbilt U)
    AMBER <-> LAMMPS tool Keir Novik (Univ College London) and Vikas Varshney (U Akron)
    CHARMM <-> LAMMPS tool Pieter in 't Veld and Paul Crozier (Sandia)
    Morse bond potential Jeff Greathouse (Sandia)
    radial distribution functions Paul Crozier & Jeff Greathouse (Sandia)
    force tables for long-range Coulombics Paul Crozier (Sandia)
    targeted molecular dynamics (TMD) Paul Crozier (Sandia) and Christian Burisch (Bochum University, Germany)
    FFT support for SGI SCSL (Altix) Jim Shepherd (Ga Tech)
    lmp2cfg and lmp2traj tools Ara Kooser, Jeff Greathouse, Andrey Kalinichev (Sandia)
    parallel tempering Mark Sears (Sandia)
    embedded atom method (EAM) potential Stephen Foiles (Sandia)
    multi-harmonic dihedral potential Mathias Puetz (Sandia)
    granular force fields and BC Leo Silbert & Gary Grest (Sandia)
    2d Ewald/PPPM Paul Crozier (Sandia)
    CHARMM force fields Paul Crozier (Sandia)
    msi2lmp tool Steve Lustig (Dupont), Mike Peachey & John Carpenter (Cray)
    HTFN energy minimizer Todd Plantenga (Sandia)
    class 2 force fields Eric Simon (Cray)
    NVT/NPT integrators Mark Stevens (Sandia)
    rRESPA Mark Stevens & Paul Crozier (Sandia)
    Ewald and PPPM solvers Roy Pollock (LLNL) -
    - -

    Other CRADA partners involved in the design and testing of LAMMPS were +

    • Axel Kohlmeyer (Temple U), akohlmey at gmail.com, SVN and Git repositories, indefatigable mail list responder, USER-CG-CMM and USER-OMP packages +
    • Roy Pollock (LLNL), Ewald and PPPM solvers +
    • Mike Brown (ORNL), brownw at ornl.gov, GPU package +
    • Greg Wagner (Sandia), gjwagne at sandia.gov, MEAM package for MEAM potential +
    • Mike Parks (Sandia), mlparks at sandia.gov, PERI package for Peridynamics +
    • Rudra Mukherjee (JPL), Rudranarayan.M.Mukherjee at jpl.nasa.gov, POEMS package for articulated rigid body motion +
    • Reese Jones (Sandia) and collaborators, rjones at sandia.gov, USER-ATC package for atom/continuum coupling +
    • Ilya Valuev (JIHT), valuev at physik.hu-berlin.de, USER-AWPMD package for wave-packet MD +
    • Christian Trott (U Tech Ilmenau), christian.trott at tu-ilmenau.de, USER-CUDA package +
    • Andres Jaramillo-Botero (Caltech), ajaramil at wag.caltech.edu, USER-EFF package for electron force field +
    • Pieter in' t Veld (BASF), pieter.intveld at basf.com, USER-EWALDN package for 1/r^N long-range solvers +
    • Christoph Kloss (JKU), Christoph.Kloss at jku.at, USER-LIGGGHTS package for granular models and granular/fluid coupling +
    • Metin Aktulga (LBL), hmaktulga at lbl.gov, USER-REAXC package for C version of ReaxFF +
    • Georg Gunzenmuller (EMI), georg.ganzenmueller at emi.fhg.de, USER-SPH package +
    +

    As discussed in this section, LAMMPS originated +as a cooperative project between DOE labs and industrial +partners. Folks involved in the design and testing of the original +version of LAMMPS were the following:

    • John Carpenter (Mayo Clinic, formerly at Cray Research)
    • Terry Stouch (Lexicon Pharmaceuticals, formerly at Bristol Myers Squibb) diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 9dde846b6d..8422fdd8bd 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -463,165 +463,59 @@ Hierarchical Modeling". :link(oascr,http://www.sc.doe.gov/ascr/home.html) :link(ober,http://www.er.doe.gov/production/ober/ober_top.html) -The following papers describe the parallel algorithms used in LAMMPS. +The following paper describe the basic parallel algorithms used in +LAMMPS. If you use LAMMPS results in your published work, please cite +this paper and include a pointer to the "LAMMPS WWW Site"_lws +(http://lammps.sandia.gov): S. J. Plimpton, [Fast Parallel Algorithms for Short-Range Molecular Dynamics], J Comp Phys, 117, 1-19 (1995). -S. J. Plimpton, R. Pollock, M. Stevens, [Particle-Mesh Ewald and -rRESPA for Parallel Molecular Dynamics Simulations], in Proc of the -Eighth SIAM Conference on Parallel Processing for Scientific -Computing, Minneapolis, MN (March 1997). +Other papers describing specific algorithms used in LAMMPS are listed +under the "Citing LAMMPS link"_http://lammps.sandia.gov/cite.html of +the LAMMPS WWW page. -If you use LAMMPS results in your published work, please cite the J -Comp Phys reference and include a pointer to the "LAMMPS WWW Site"_lws -(http://lammps.sandia.gov). +The "Publications link"_http://lammps.sandia.gov/papers.html on the +LAMMPS WWW page lists papers that have cited LAMMPS. If your paper is +not listed there for some reason, feel free to send us the info. If +the simulations in your paper produced cool pictures or animations, +we'll be pleased to add them to the +"Pictures"_http://lammps.sandia.gov/pictures.html or +"Movies"_http://lammps.sandia.gov/movies.html pages of the LAMMPS WWW +site. -If you send is information about your publication, we'll be pleased to -add it to the Publications page of the "LAMMPS WWW Site"_lws. Ditto -for a picture or movie for the Pictures or Movies pages. +The core group of LAMMPS developers is at Sandia National Labs: -The core group of LAMMPS developers is at Sandia National Labs. They -include "Steve Plimpton"_sjp, Paul Crozier, and Aidan Thompson and can -be contacted via email: sjplimp, pscrozi, athomps at sandia.gov. +Steve Plimpton, sjplimp at sandia.gov +Aidan Thompson, athomps at sandia.gov +Paul Crozier, pscrozi at sandia.gov :ul -Here are various folks who have made significant contributions to -features in LAMMPS. The most recent contributions are at the top of -the list. +The following folks are responsible for significant contributions to +the code, or other aspects of the LAMMPS development effort. Many of +the packages they have written are somewhat unique to LAMMPS and the +code would not be as general-purpose as it is without their expertise +and efforts. -:link(sjp,http://www.sandia.gov/~sjplimp) +Axel Kohlmeyer (Temple U), akohlmey at gmail.com, SVN and Git repositories, indefatigable mail list responder, USER-CG-CMM and USER-OMP packages +Roy Pollock (LLNL), Ewald and PPPM solvers +Mike Brown (ORNL), brownw at ornl.gov, GPU package +Greg Wagner (Sandia), gjwagne at sandia.gov, MEAM package for MEAM potential +Mike Parks (Sandia), mlparks at sandia.gov, PERI package for Peridynamics +Rudra Mukherjee (JPL), Rudranarayan.M.Mukherjee at jpl.nasa.gov, POEMS package for articulated rigid body motion +Reese Jones (Sandia) and collaborators, rjones at sandia.gov, USER-ATC package for atom/continuum coupling +Ilya Valuev (JIHT), valuev at physik.hu-berlin.de, USER-AWPMD package for wave-packet MD +Christian Trott (U Tech Ilmenau), christian.trott at tu-ilmenau.de, USER-CUDA package +Andres Jaramillo-Botero (Caltech), ajaramil at wag.caltech.edu, USER-EFF package for electron force field +Pieter in' t Veld (BASF), pieter.intveld at basf.com, USER-EWALDN package for 1/r^N long-range solvers +Christoph Kloss (JKU), Christoph.Kloss at jku.at, USER-LIGGGHTS package for granular models and granular/fluid coupling +Metin Aktulga (LBL), hmaktulga at lbl.gov, USER-REAXC package for C version of ReaxFF +Georg Gunzenmuller (EMI), georg.ganzenmueller at emi.fhg.de, USER-SPH package :ul -pppm GPU single and double : Mike Brown (ORNL) -pair_style lj/cut/expand : Inderaj Bains (NVIDIA) -temperature accelerated dynamics (TAD) : Aidan Thompson (Sandia) -pair reax/c and fix qeq/reax : Metin Aktulga (Purdue, now LBNL) -DREIDING force field, pair_style hbond/dreiding, etc : Tod Pascal (CalTech) -fix adapt and compute ti for thermodynamic integreation for free energies : Sai Jayaraman (Sandia) -pair born and pair gauss : Sai Jayaraman (Sandia) -stochastic rotation dynamics (SRD) via fix srd : Jemery Lechman (Sandia) and Pieter in 't Veld (BASF) -ipp Perl script tool : Reese Jones (Sandia) -eam_database and createatoms tools : Xiaowang Zhou (Sandia) -electron force field (eFF) : Andres Jaramillo-Botero and Julius Su (Caltech) -embedded ion method (EIM) potential : Xiaowang Zhou (Sandia) -COMB potential with charge equilibration : Tzu-Ray Shan (U Florida) -fix ave/correlate : Benoit Leblanc, Dave Rigby, Paul Saxe (Materials Design) and Reese Jones (Sandia) -pair_style peri/lps : Mike Parks (Sandia) -fix msst : Lawrence Fried (LLNL), Evan Reed (LLNL, Stanford) -thermo_style custom tpcpu & spcpu keywords : Axel Kohlmeyer (Temple U) -fix rigid/nve, fix rigid/nvt : Tony Sheh and Trung Dac Nguyen (U Michigan) -public SVN & Git repositories for LAMMPS : Axel Kohlmeyer (Temple U) and Bill Goldman (Sandia) -fix nvt, fix nph, fix npt, Parinello/Rahman dynamics, fix box/relax : Aidan Thompson (Sandia) -compute heat/flux : German Samolyuk (ORNL) and Mario Pinto (Computational Research Lab, Pune, India) -pair yukawa/colloid : Randy Schunk (Sandia) -fix wall/colloid : Jeremy Lechman (Sandia) -pair_style dsmc for Direct Simulation Monte Carlo (DSMC) modeling : Paul Crozier (Sandia) -fix imd for real-time viz and interactive MD : Axel Kohlmeyer (Temple Univ) -concentration-dependent EAM potential : Alexander Stukowski (Technical University of Darmstadt) -parallel replica dymamics (PRD) : Mike Brown (Sandia) -min_style hftn : Todd Plantenga (Sandia) -fix atc : Reese Jones, Jon Zimmerman, Jeremy Templeton (Sandia) -dump cfg : Liang Wan (Chinese Academy of Sciences) -fix nvt with Nose/Hoover chains : Andy Ballard (U Maryland) -pair_style lj/cut/gpu, pair_style gayberne/gpu : Mike Brown (Sandia) -pair_style lj96/cut, bond_style table, angle_style table : Chuanfu Luo -fix langevin tally : Carolyn Phillips (U Michigan) -compute heat/flux for Green-Kubo : Reese Jones (Sandia), Philip Howell (Siemens), Vikas Varsney (AFRL) -region cone : Pim Schravendijk -fix reax/bonds : Aidan Thompson (Sandia) -pair born/coul/long : Ahmed Ismail (Sandia) -fix ttm : Paul Crozier (Sandia) and Carolyn Phillips (U Michigan) -fix box/relax : Aidan Thompson and David Olmsted (Sandia) -ReaxFF potential : Aidan Thompson (Sandia) and Hansohl Cho (MIT) -compute cna/atom : Wan Liang (Chinese Academy of Sciences) -Tersoff/ZBL potential : Dave Farrell (Northwestern U) -peridynamics : Mike Parks (Sandia) -fix smd for steered MD : Axel Kohlmeyer (U Penn) -GROMACS pair potentials : Mark Stevens (Sandia) -lmp2vmd tool : Axel Kohlmeyer (U Penn) -compute group/group : Naveen Michaud-Agrawal (Johns Hopkins U) -USER-CG-CMM package for coarse-graining : Axel Kohlmeyer (U Penn) -cosine/delta angle potential : Axel Kohlmeyer (U Penn) -VIM editor add-ons for LAMMPS input scripts : Gerolf Ziegenhain -pair lubricate : Randy Schunk (Sandia) -compute ackland/atom : Gerolf Zeigenhain -kspace_style ewald/n, pair_style lj/coul, pair_style buck/coul : \ - Pieter in 't Veld (Sandia) -AIREBO bond-order potential : Ase Henry (MIT) -making LAMMPS a true "object" that can be instantiated multiple times, \ - e.g. as a library : Ben FrantzDale (RPI) -pymol_asphere viz tool : Mike Brown (Sandia) -NEMD SLLOD integration : Pieter in 't Veld (Sandia) -tensile and shear deformations : Pieter in 't Veld (Sandia) -GayBerne potential : Mike Brown (Sandia) -ellipsoidal particles : Mike Brown (Sandia) -colloid potentials : Pieter in 't Veld (Sandia) -fix heat : Paul Crozier and Ed Webb (Sandia) -neighbor multi and communicate multi : Pieter in 't Veld (Sandia) -MATLAB post-processing scripts : Arun Subramaniyan (Purdue) -triclinic (non-orthogonal) simulation domains : Pieter in 't Veld (Sandia) -thermo_extract tool: Vikas Varshney (Wright Patterson AFB) -fix ave/time and fix ave/spatial : Pieter in 't Veld (Sandia) -MEAM potential : Greg Wagner (Sandia) -optimized pair potentials for lj/cut, charmm/long, eam, morse : \ - James Fischer (High Performance Technologies), \ - David Richie and Vincent Natoli (Stone Ridge Technologies) -fix wall/lj126 : Mark Stevens (Sandia) -Stillinger-Weber and Tersoff potentials : Aidan Thompson and Xiaowang Zhou (Sandia) -region prism : Pieter in 't Veld (Sandia) -LJ tail corrections for energy/pressure : Paul Crozier (Sandia) -fix momentum and recenter : Naveen Michaud-Agrawal (Johns Hopkins U) -multi-letter variable names : Naveen Michaud-Agrawal (Johns Hopkins U) -OPLS dihedral potential: Mark Stevens (Sandia) -POEMS coupled rigid body integrator: Rudranarayan Mukherjee (RPI) -faster pair hybrid potential: James Fischer \ - (High Performance Technologies, Inc), Vincent Natoli and \ - David Richie (Stone Ridge Technology) -breakable bond quartic potential: Chris Lorenz and Mark Stevens (Sandia) -DCD and XTC dump styles: Naveen Michaud-Agrawal (Johns Hopkins U) -grain boundary orientation fix : Koenraad Janssens and David Olmsted (Sandia) -lj/smooth pair potential : Craig Maloney (UCSB) -radius-of-gyration spring fix : Naveen Michaud-Agrawal (Johns Hopkins U) and \ - Paul Crozier (Sandia) -self spring fix : Naveen Michaud-Agrawal (Johns Hopkins U) -EAM CoAl and AlCu potentials : Kwang-Reoul Lee (KIST, Korea) -cosine/squared angle potential : Naveen Michaud-Agrawal (Johns Hopkins U) -helix dihedral potential : Naveen Michaud-Agrawal (Johns Hopkins U) and \ - Mark Stevens (Sandia) -Finnis/Sinclair EAM: Tim Lau (MIT) -dissipative particle dynamics (DPD) potentials: Kurt Smith (U Pitt) and \ - Frank van Swol (Sandia) -TIP4P potential (4-site water): Ahmed Ismail and Amalie Frischknecht (Sandia) -uniaxial strain fix: Carsten Svaneborg (Max Planck Institute) -thermodynamics enhanced by fix quantities: Aidan Thompson (Sandia) -compressed dump files: Erik Luijten (U Illinois) -cylindrical indenter fix: Ravi Agrawal (Northwestern U) -electric field fix: Christina Payne (Vanderbilt U) -AMBER <-> LAMMPS tool: Keir Novik (Univ College London) and \ - Vikas Varshney (U Akron) -CHARMM <-> LAMMPS tool: Pieter in 't Veld and Paul Crozier (Sandia) -Morse bond potential: Jeff Greathouse (Sandia) -radial distribution functions: Paul Crozier & Jeff Greathouse (Sandia) -force tables for long-range Coulombics: Paul Crozier (Sandia) -targeted molecular dynamics (TMD): Paul Crozier (Sandia) and \ - Christian Burisch (Bochum University, Germany) -FFT support for SGI SCSL (Altix): Jim Shepherd (Ga Tech) -lmp2cfg and lmp2traj tools: Ara Kooser, Jeff Greathouse, \ - Andrey Kalinichev (Sandia) -parallel tempering: Mark Sears (Sandia) -embedded atom method (EAM) potential: Stephen Foiles (Sandia) -multi-harmonic dihedral potential: Mathias Puetz (Sandia) -granular force fields and BC: Leo Silbert & Gary Grest (Sandia) -2d Ewald/PPPM: Paul Crozier (Sandia) -CHARMM force fields: Paul Crozier (Sandia) -msi2lmp tool: Steve Lustig (Dupont), Mike Peachey & John Carpenter (Cray) -HTFN energy minimizer: Todd Plantenga (Sandia) -class 2 force fields: Eric Simon (Cray) -NVT/NPT integrators: Mark Stevens (Sandia) -rRESPA: Mark Stevens & Paul Crozier (Sandia) -Ewald and PPPM solvers: Roy Pollock (LLNL) : :tb(s=:) +As discussed in "this section"_Section_history.html, LAMMPS originated +as a cooperative project between DOE labs and industrial +partners. Folks involved in the design and testing of the original +version of LAMMPS were the following: -Other CRADA partners involved in the design and testing of LAMMPS were - John Carpenter (Mayo Clinic, formerly at Cray Research) Terry Stouch (Lexicon Pharmaceuticals, formerly at Bristol Myers Squibb) Steve Lustig (Dupont) From 2eedcc161e590cfe389d08e652042d19de0bdf4d Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 02:38:32 +0000 Subject: [PATCH 095/246] Added fix nphug docs git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6918 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_msst.html | 2 +- doc/fix_msst.txt | 2 +- doc/fix_nh.html | 2 +- doc/fix_nh.txt | 2 +- doc/fix_nphug.html | 219 +++++++++++++++++++++++++++++++++++++++++++++ doc/fix_nphug.txt | 211 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 doc/fix_nphug.html create mode 100644 doc/fix_nphug.txt diff --git a/doc/fix_msst.html b/doc/fix_msst.html index 8be90641a8..60f2daffe7 100644 --- a/doc/fix_msst.html +++ b/doc/fix_msst.html @@ -155,7 +155,7 @@ all.

      Related commands:

      -

      fix deform +

      fix nphug, fix deform

      Default:

      diff --git a/doc/fix_msst.txt b/doc/fix_msst.txt index 0a606bf814..60dbc1f20d 100644 --- a/doc/fix_msst.txt +++ b/doc/fix_msst.txt @@ -145,7 +145,7 @@ all. [Related commands:] -"fix deform"_fix_deform.html +"fix nphug"_fix_nphug.html, "fix deform"_fix_deform.html [Default:] diff --git a/doc/fix_nh.html b/doc/fix_nh.html index 49165c16ce..6bf376ba76 100644 --- a/doc/fix_nh.html +++ b/doc/fix_nh.html @@ -28,7 +28,7 @@
    • style_name = nvt or npt or nph
      one or more keyword value pairs may be appended
      -keyword = temp or iso or aniso or tri or x or y or z or xy or yz or xz or couple or tchain or pchain or mtk or tloop or ploop or nreset or drag or dilate
      +keyword = temp or iso or aniso or tri or x or y or z or xy or yz or xz or couple or tchain or pchain or mtk or tloop or ploop or nreset or drag or dilate or scaleyz or scalexz or scalexy
         temp values = Tstart Tstop Tdamp
           Tstart,Tstop = external temperature at start/end of run
           Tdamp = temperature damping parameter (time units)
      diff --git a/doc/fix_nh.txt b/doc/fix_nh.txt
      index 4b4ea236e5..f7dd7f2561 100644
      --- a/doc/fix_nh.txt
      +++ b/doc/fix_nh.txt
      @@ -19,7 +19,7 @@ fix ID group-ID style_name keyword value ... :pre
       ID, group-ID are documented in "fix"_fix.html command :ulb,l
       style_name = {nvt} or {npt} or {nph} :l
       one or more keyword value pairs may be appended
      -keyword = {temp} or {iso} or {aniso} or {tri} or {x} or {y} or {z} or {xy} or {yz} or {xz} or {couple} or {tchain} or {pchain} or {mtk} or {tloop} or {ploop} or {nreset} or {drag} or {dilate}
      +keyword = {temp} or {iso} or {aniso} or {tri} or {x} or {y} or {z} or {xy} or {yz} or {xz} or {couple} or {tchain} or {pchain} or {mtk} or {tloop} or {ploop} or {nreset} or {drag} or {dilate} or {scaleyz} or {scalexz} or {scalexy}
         {temp} values = Tstart Tstop Tdamp
           Tstart,Tstop = external temperature at start/end of run
           Tdamp = temperature damping parameter (time units)
      diff --git a/doc/fix_nphug.html b/doc/fix_nphug.html
      new file mode 100644
      index 0000000000..e4ad3a3f2e
      --- /dev/null
      +++ b/doc/fix_nphug.html
      @@ -0,0 +1,219 @@
      +
      +
      LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
      + + + + + + +
      + +

      fix nphug command +

      +

      Syntax: +

      +
      fix ID group-ID nphug keyword value ... 
      +
      +
      • ID, group-ID are documented in fix command + +
        one or more keyword value pairs may be appended
        +keyword = temp or iso or aniso or tri or x or y or z or couple or tchain or pchain or mtk or tloop or ploop or nreset or drag or dilate or scaleyz or scalexz or scalexy
        +  temp values = Value1 Value2 Tdamp
        +    Value1, Value2 = Nose-Hoover target temperatures, ignored by Hugoniostat
        +    Tdamp = temperature damping parameter (time units)
        +  iso or aniso or tri values = Pstart Pstop Pdamp
        +    Pstart,Pstop = scalar external pressures, must be equal (pressure units)
        +    Pdamp = pressure damping parameter (time units)
        +  x or y or z or xy or yz or xz values = Pstart Pstop Pdamp
        +    Pstart,Pstop = external stress tensor components, must be equal (pressure units)
        +    Pdamp = stress damping parameter (time units)
        +  couple = none or xyz or xy or yz or xz
        +  tchain value = length of thermostat chain (1 = single thermostat)
        +  pchain values = length of thermostat chain on barostat (0 = no thermostat)
        +  mtk value = yes or no = add in MTK adjustment term or not
        +  tloop value = number of sub-cycles to perform on thermostat
        +  ploop value = number of sub-cycles to perform on barostat thermostat
        +  nreset value = reset reference cell every this many timesteps
        +  drag value = drag factor added to barostat/thermostat (0.0 = no drag)
        +  dilate value = all or partial
        +  scaleyz value = yes or no = scale yz with lz
        +  scalexz value = yes or no = scale xz with lz
        +  scalexy value = yes or no = scale xy with ly 
        +
        + +
      +

      Examples: +

      +

      fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0 +fix myhug all nphug temp 1.0 1.0 10.0 iso 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 +

      +

      Description: +

      +

      This command is a variant of the Nose-Hoover +fix npt fix style. +It performs time integration of the Hugoniostat equations +of motion developed by Ravelo et al. (Ravelo). +These equations compress the system to a state with average +axial stress or pressure equal to the specified target value +and that satisfies the Rankine-Hugoniot (RH) +jump conditions for steady shocks. +

      +

      The compression can be performed +either +hydrostatically (using keyword iso, aniso, or tri) or uniaxially +(using keywords x, y, or z). In the hydrostatic case, +the cell dimensions change dynamically so that the average axial stress +in all three directions converges towards the specified target value. +In the uniaxial case, the chosen cell dimension changes dynamically +so that the average +axial stress in that direction converges towards the target value. The +other two cell dimensions are kept fixed (zero lateral strain). +

      +

      This leads to the following additional restrictions on the keywords: +

      +

      One and only one of the following keywords should be used: iso, aniso, tri, x, y, z, +

      +

      The specified initial and final target pressures must be the same. +

      +

      The keywords xy, xz, yz may not be used. +

      +

      The only admissible value for the couple keyword is xyz, +which has the same effect as keyword iso +

      +
      • The temp keyword must be used in order to specify the time constant for +
      • kinetic energy relaxation, but initial and final target temperature values +
      • are ignored. +
      +

      Essentially, a Hugoniostat simulation is an NPT simulation in which the +user-specified target temperature is replaced with a time-dependent +target temperature Tt obtained from the following equation: +

      +

      Tt - T = (0.5*(P+P0)(V0-V)+E0-E)/(Ndof kB) = Delta +

      +

      where T and Tt are the instantaneous and target temperatures, +P and P0 are the instantaneous and reference pressure or axial stress, +depending on whether hydrostatic or uniaxial compression is being +performed, V and V0 are the instantaneous and reference volumes, +E and E0 are the instantaneous and reference internal energy (potential +plus kinetic), Ndof is the number of degrees of freedom used in the +definition of temperature, and kB is the Boltzmann constant. Delta is the +negative deviation of the instantaneous temperature from the target temperature. +The values of E0, V0, and P0 are the instantaneous values at the start of +the simulation. These can be overridden using the fix_modify keywords e0, +v0, and p0 described below. +

      +
      + +

      IMPORTANT NOTE: Unlike the fix +temp/berendsen command which performs +thermostatting but NO time integration, this fix performs +thermostatting/barostatting AND time integration. Thus you should not +use any other time integration fix, such as fix nve on +atoms to which this fix is applied. Likewise, this fix should not be +used on atoms that have their temperature controlled by another fix +- e.g. by fix langevin or fix temp/rescale +commands. +

      +
      + +

      This fix compute a temperature and pressure each timestep. To do +this, the fix creates its own computes of style "temp" and "pressure", +as if one of these two sets of commands had been issued: +

      +
      compute fix-ID_temp group-ID temp
      +compute fix-ID_press group-ID pressure fix-ID_temp 
      +
      +
      compute fix-ID_temp all temp
      +compute fix-ID_press all pressure fix-ID_temp 
      +
      +

      See the compute temp and compute +pressure commands for details. Note that the +IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID ++ underscore + "press". For fix nvt, the group for the new computes +is the same as the fix group. For fix nph and fix npt, the group for +the new computes is "all" since pressure is computed for the entire +system. +

      +

      Note that these are NOT the computes used by thermodynamic output (see +the thermo_style command) with ID = thermo_temp +and thermo_press. This means you can change the attributes of this +fix's temperature or pressure via the +compute_modify command or print this temperature +or pressure during thermodynamic output via the thermo_style +custom command using the appropriate compute-ID. +It also means that changing attributes of thermo_temp or +thermo_press will have no effect on this fix. +

      +
      + +

      Restart, fix_modify, output, run start/stop, minimize info: +

      +

      This fix writes the values of E0, V0, and P0, as well as the +state of all the thermostat and barostat +variables to binary restart files. See the +read_restart command for info on how to re-specify +a fix in an input script that reads a restart file, so that the +operation of the fix continues in an uninterrupted fashion. +

      +

      The fix_modify e0, v0 and p0 keywords +can be used to define the values of these quantities. Note the +the values for e0 and v0 are extensive, and so must correspond +to the total energy and volume of the entire system, not energy and +volume per atom. If any of these quantities are not specified, then the +instanteous value in the system at the start of the simulation is used. +

      +

      The fix_modify temp and press options are +supported by these fixes. You can use them to assign a +compute you have defined to this fix which will be used +in its thermostatting or barostatting procedure, as described above. +If you do this, note that the kinetic energy derived from the compute +temperature should be consistent with the virial term computed using +all atoms for the pressure. LAMMPS will warn you if you choose to +compute temperature on a subset of atoms. +

      +

      The fix_modify energy option is supported by these +fixes to add the energy change induced by Nose/Hoover thermostatting +and barostatting to the system's potential energy as part of +thermodynamic output. Either way, this energy is *not* +included in the definition of internal energy E when calculating the value +of Delta in the above equation. +

      +

      These fixes compute a global scalar and a global vector of quantities, +which can be accessed by various output +commands. The scalar value calculated by +these fixes is "extensive"; the vector values are "intensive". +

      +

      The scalar is the cumulative energy change due to the fix. +

      +

      The vector stores three quantities unique to this fix (Delta, Us, and up), +followed by all the internal Nose/Hoover thermostat and barostat +variables defined for fix_style npt. Delta is the deviation +of the temperature from the target temperature, given by the above equation. +Us and up are the shock and particle velocity correspponding to a steady +shock calculated from the Rh conditions. They have units of distance/time. +

      +

      Restrictions: +

      +

      This fix style is part of the SHOCK package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

      +

      All the usual restrictions for fix_style npt apply, +plus the additional ones mentioned above. +

      +

      Related commands: +

      +

      fix msst, fix npt, fix_modify +

      +

      Default: +

      +

      The keyword defaults are the same as those for fix npt +

      +
      + + + +

      (Ravelo) Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004). +

      + diff --git a/doc/fix_nphug.txt b/doc/fix_nphug.txt new file mode 100644 index 0000000000..6bb5664302 --- /dev/null +++ b/doc/fix_nphug.txt @@ -0,0 +1,211 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix nphug command :h3 + +[Syntax:] + +fix ID group-ID nphug keyword value ... :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +one or more keyword value pairs may be appended +keyword = {temp} or {iso} or {aniso} or {tri} or {x} or {y} or {z} or {couple} or {tchain} or {pchain} or {mtk} or {tloop} or {ploop} or {nreset} or {drag} or {dilate} or {scaleyz} or {scalexz} or {scalexy} + {temp} values = Value1 Value2 Tdamp + Value1, Value2 = Nose-Hoover target temperatures, ignored by Hugoniostat + Tdamp = temperature damping parameter (time units) + {iso} or {aniso} or {tri} values = Pstart Pstop Pdamp + Pstart,Pstop = scalar external pressures, must be equal (pressure units) + Pdamp = pressure damping parameter (time units) + {x} or {y} or {z} or {xy} or {yz} or {xz} values = Pstart Pstop Pdamp + Pstart,Pstop = external stress tensor components, must be equal (pressure units) + Pdamp = stress damping parameter (time units) + {couple} = {none} or {xyz} or {xy} or {yz} or {xz} + {tchain} value = length of thermostat chain (1 = single thermostat) + {pchain} values = length of thermostat chain on barostat (0 = no thermostat) + {mtk} value = {yes} or {no} = add in MTK adjustment term or not + {tloop} value = number of sub-cycles to perform on thermostat + {ploop} value = number of sub-cycles to perform on barostat thermostat + {nreset} value = reset reference cell every this many timesteps + {drag} value = drag factor added to barostat/thermostat (0.0 = no drag) + {dilate} value = {all} or {partial} + {scaleyz} value = {yes} or {no} = scale yz with lz + {scalexz} value = {yes} or {no} = scale xz with lz + {scalexy} value = {yes} or {no} = scale xy with ly :pre +:ule + +[Examples:] + +fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0 +fix myhug all nphug temp 1.0 1.0 10.0 iso 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 + +[Description:] + +This command is a variant of the Nose-Hoover +"fix npt"_fix_nh.html fix style. +It performs time integration of the Hugoniostat equations +of motion developed by Ravelo et al. "(Ravelo)"_#Ravelo. +These equations compress the system to a state with average +axial stress or pressure equal to the specified target value +and that satisfies the Rankine-Hugoniot (RH) +jump conditions for steady shocks. + +The compression can be performed +either +hydrostatically (using keyword iso, aniso, or tri) or uniaxially +(using keywords x, y, or z). In the hydrostatic case, +the cell dimensions change dynamically so that the average axial stress +in all three directions converges towards the specified target value. +In the uniaxial case, the chosen cell dimension changes dynamically +so that the average +axial stress in that direction converges towards the target value. The +other two cell dimensions are kept fixed (zero lateral strain). + +This leads to the following additional restrictions on the keywords: + +One and only one of the following keywords should be used: iso, aniso, tri, x, y, z, + +The specified initial and final target pressures must be the same. + +The keywords xy, xz, yz may not be used. + +The only admissible value for the couple keyword is xyz, +which has the same effect as keyword iso + +The temp keyword must be used in order to specify the time constant for +kinetic energy relaxation, but initial and final target temperature values +are ignored. :ul + +Essentially, a Hugoniostat simulation is an NPT simulation in which the +user-specified target temperature is replaced with a time-dependent +target temperature Tt obtained from the following equation: + +Tt - T = (0.5*(P+P0)(V0-V)+E0-E)/(Ndof kB) = Delta + +where T and Tt are the instantaneous and target temperatures, +P and P0 are the instantaneous and reference pressure or axial stress, +depending on whether hydrostatic or uniaxial compression is being +performed, V and V0 are the instantaneous and reference volumes, +E and E0 are the instantaneous and reference internal energy (potential +plus kinetic), Ndof is the number of degrees of freedom used in the +definition of temperature, and kB is the Boltzmann constant. Delta is the +negative deviation of the instantaneous temperature from the target temperature. +The values of E0, V0, and P0 are the instantaneous values at the start of +the simulation. These can be overridden using the fix_modify keywords {e0}, +{v0}, and {p0} described below. + +:line + +IMPORTANT NOTE: Unlike the "fix +temp/berendsen"_fix_temp_berendsen.html command which performs +thermostatting but NO time integration, this fix performs +thermostatting/barostatting AND time integration. Thus you should not +use any other time integration fix, such as "fix nve"_fix_nve.html on +atoms to which this fix is applied. Likewise, this fix should not be +used on atoms that have their temperature controlled by another fix +- e.g. by "fix langevin"_fix_nh.html or "fix temp/rescale"_fix_temp_rescale.html +commands. + +:line + +This fix compute a temperature and pressure each timestep. To do +this, the fix creates its own computes of style "temp" and "pressure", +as if one of these two sets of commands had been issued: + +compute fix-ID_temp group-ID temp +compute fix-ID_press group-ID pressure fix-ID_temp :pre + +compute fix-ID_temp all temp +compute fix-ID_press all pressure fix-ID_temp :pre + +See the "compute temp"_compute_temp.html and "compute +pressure"_compute_pressure.html commands for details. Note that the +IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID ++ underscore + "press". For fix nvt, the group for the new computes +is the same as the fix group. For fix nph and fix npt, the group for +the new computes is "all" since pressure is computed for the entire +system. + +Note that these are NOT the computes used by thermodynamic output (see +the "thermo_style"_thermo_style.html command) with ID = {thermo_temp} +and {thermo_press}. This means you can change the attributes of this +fix's temperature or pressure via the +"compute_modify"_compute_modify.html command or print this temperature +or pressure during thermodynamic output via the "thermo_style +custom"_thermo_style.html command using the appropriate compute-ID. +It also means that changing attributes of {thermo_temp} or +{thermo_press} will have no effect on this fix. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +This fix writes the values of E0, V0, and P0, as well as the +state of all the thermostat and barostat +variables to "binary restart files"_restart.html. See the +"read_restart"_read_restart.html command for info on how to re-specify +a fix in an input script that reads a restart file, so that the +operation of the fix continues in an uninterrupted fashion. + +The "fix_modify"_fix_modify.html {e0}, {v0} and {p0} keywords +can be used to define the values of these quantities. Note the +the values for {e0} and {v0} are extensive, and so must correspond +to the total energy and volume of the entire system, not energy and +volume per atom. If any of these quantities are not specified, then the +instanteous value in the system at the start of the simulation is used. + +The "fix_modify"_fix_modify.html {temp} and {press} options are +supported by these fixes. You can use them to assign a +"compute"_compute.html you have defined to this fix which will be used +in its thermostatting or barostatting procedure, as described above. +If you do this, note that the kinetic energy derived from the compute +temperature should be consistent with the virial term computed using +all atoms for the pressure. LAMMPS will warn you if you choose to +compute temperature on a subset of atoms. + +The "fix_modify"_fix_modify.html {energy} option is supported by these +fixes to add the energy change induced by Nose/Hoover thermostatting +and barostatting to the system's potential energy as part of +"thermodynamic output"_thermo_style.html. Either way, this energy is *not* +included in the definition of internal energy E when calculating the value +of Delta in the above equation. + +These fixes compute a global scalar and a global vector of quantities, +which can be accessed by various "output +commands"_Section_howto.html#howto_15. The scalar value calculated by +these fixes is "extensive"; the vector values are "intensive". + +The scalar is the cumulative energy change due to the fix. + +The vector stores three quantities unique to this fix (Delta, Us, and up), +followed by all the internal Nose/Hoover thermostat and barostat +variables defined for "fix_style npt"_fix_nh.html. Delta is the deviation +of the temperature from the target temperature, given by the above equation. +Us and up are the shock and particle velocity correspponding to a steady +shock calculated from the Rh conditions. They have units of distance/time. + +[Restrictions:] + +This fix style is part of the SHOCK package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +All the usual restrictions for "fix_style npt"_fix_nh.html apply, +plus the additional ones mentioned above. + +[Related commands:] + +"fix msst"_fix_msst.html, "fix npt"_fix_nh.html, "fix_modify"_fix_modify.html + +[Default:] + +The keyword defaults are the same as those for "fix npt"_fix_nh.html + +:line + +:link(Ravelo) +[(Ravelo)] Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004). From 1f4bb3fb47c86dd9eeb89e4ea2db1c0155e01e99 Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 02:40:00 +0000 Subject: [PATCH 096/246] Finished fix nphug git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6919 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 332 +++++++++++++++++++++++++++++++--------- src/SHOCK/fix_nphug.h | 13 +- 2 files changed, 268 insertions(+), 77 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 0a2c3cded4..02e744cc9c 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -11,55 +11,8 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* - - This fix applies the NPHug Hugoniostat method of Ravelo et al. - -(Ravelo, Holian, Germann, and Lomdahl, PRB 70 014103 (2004)) - -It uses the Nose-Hoover thermostat and barostat (fix_nh.html). -The Nose-Hoover barostat is used to compress the system -to a specified final stress state. This is done either -hydrostatically (using keyword iso, aniso, or tri) or uniaxially -(using keywords x, y, or z). In the hydrostatic case, -the cell dimensions change dynamically so that the average axial stress -in all three directions converges towards the specified target value. -In the uniaxial case, the chosen cell dimension changes dynamically -so that the average -axial stress in that direction converges towards the target value. The -other two cell dimensions are kept fixed (zero lateral strain). - -This leads to the following restrictions on the keywords: - -- The specified initial and -final target pressures must be the same. - -- Only one of the following keywords may be used: -iso, aniso, tri, x, y, z, - -- The keywords xy, xz, yz may not be used. - -- The only admissible value for the couple keyword is xyz, -which has the same effect as keyword iso - -- The drag parameter is proportional to the beta_H and beta_p -damping coefficients in the Ravelo paper. - -- The temp keyword serves only to set the value of tdamp. The initial -and final target temperatures are ignored. - -- The values of tdamp and pdamp are inversely proportional to the -coupling rate nu_H and nu_p in the Ravelo paper - -- All other keywords function in the same way. - -*/ - - - - - #include "string.h" +#include "stdlib.h" #include "fix_nphug.h" #include "modify.h" #include "error.h" @@ -67,26 +20,91 @@ coupling rate nu_H and nu_p in the Ravelo paper #include "compute.h" #include "force.h" #include "domain.h" +#include "group.h" +#include "math.h" +#include "memory.h" +#include "comm.h" +#include "math.h" using namespace LAMMPS_NS; +enum{ISO,ANISO,TRICLINIC}; // same as fix_nh.cpp + /* ---------------------------------------------------------------------- */ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { - // Hard-code to use initial state of system + + // extend vector of base-class computes + + size_vector += 3; + + // turn off deviatoric flag and remove strain energy from vector + + deviatoric_flag = 0; + size_vector -= 1; + + // use initial state as reference state v0_set = p0_set = e0_set = 0; - // Hard-code to use z direction + // check pressure settings - direction = 2; - if (p_flag[0] == 1 || p_flag[1] == 1 || - p_flag[3] == 1 || p_flag[4] == 1 || p_flag[5] == 1) - error->all("Only pressure control in z direction to be used with fix nphug"); - if (p_flag[2] == 0) - error->all("Pressure control in z direction must be used with fix nphug"); + if (p_start[0] != p_stop[0] || + p_start[1] != p_stop[1] || + p_start[2] != p_stop[2]) + error->all("Invalid argument for fix nphug"); + + // uniaxial = 0 means hydrostatic compression + // uniaxial = 1 means uniaxial compression + // in x, y, or z (idir = 0, 1, or 2) + + // isotropic hydrostatic compression + + if (pstyle == ISO) { + uniaxial = 0; + + // anisotropic compression + + } else if (pstyle == ANISO) { + + // anisotropic hydrostatic compression + + if (p_start[0] == p_start[1] && + p_start[0] == p_start[2] ) + uniaxial = 0; + + // uniaxial compression + + else if (p_flag[0] == 1 && p_flag[1] == 0 + && p_flag[2] == 0) { + uniaxial = 1; + idir = 0; + } else if (p_flag[0] == 0 && p_flag[1] == 1 + && p_flag[2] == 0) { + uniaxial = 1; + idir = 1; + } else if (p_flag[0] == 0 && p_flag[1] == 0 + && p_flag[2] == 1) { + uniaxial = 1; + idir = 2; + + } else error->all("Invalid argument for fix nphug"); + + // triclinic hydrostatic compression + + } else if (pstyle == TRICLINIC) { + + if (p_start[0] == p_start[1] && + p_start[0] == p_start[2] && + p_start[3] == 0.0 && + p_start[4] == 0.0 && + p_start[5] == 0.0 ) + uniaxial = 0; + + else error->all("Invalid argument for fix nphug"); + } if (!tstat_flag) error->all("Temperature control must be used with fix nphug"); @@ -190,8 +208,11 @@ void FixNPHug::setup(int vflag) } if ( p0_set == 0 ) { - p0 = p_current[direction]; p0_set = 1; + if (uniaxial == 1) + p0 = p_current[idir]; + else + p0 = (p_current[0]+p_current[1]+p_current[2])/3.0; } if ( e0_set == 0 ) { @@ -199,6 +220,12 @@ void FixNPHug::setup(int vflag) e0_set = 1; } + double masstot = group->mass(igroup); + rho0 = nktv2p*force->mvv2e*masstot/v0; + + t_target = 0.01; + + pe->addstep(update->ntimestep+1); } /* ---------------------------------------------------------------------- @@ -209,21 +236,9 @@ void FixNPHug::compute_temp_target() { t_target = t_current + compute_hugoniot(); ke_target = tdof * boltz * t_target; - if (ke_target < 0.0) ke_target = 0.0; - - // If t_target is very small, need to choose - // more reasonable value for use by barostat and - // thermostat masses. ke_target is left as is. - - if (t_target <= 1.0e-6) { - if (strcmp(update->unit_style,"lj") == 0) t0 = 1.0; - else t0 = 300.0; - } - pressure->addstep(update->ntimestep+1); pe->addstep(update->ntimestep+1); } - /* ---------------------------------------------------------------------- */ double FixNPHug::compute_etotal() @@ -232,7 +247,7 @@ double FixNPHug::compute_etotal() epot = pe->compute_scalar(); if (thermo_energy) epot -= compute_scalar(); ekin = temperature->compute_scalar(); - ekin *= 0.5 * temperature->dof * force->boltz; + ekin *= 0.5 * tdof * force->boltz; etot = epot+ekin; return etot; } @@ -249,24 +264,193 @@ double FixNPHug::compute_vol() /* ---------------------------------------------------------------------- Computes the deviation of the current point - from the Hugoniot in energy units. + from the Hugoniot in temperature units. ------------------------------------------------------------------------- */ double FixNPHug::compute_hugoniot() { - double v, e, p; + double v,e,p; double dhugo; e = compute_etotal(); temperature->compute_vector(); - pressure->compute_vector(); - p = pressure->vector[direction]; + + + if (uniaxial == 1) { + pressure->compute_vector(); + p = pressure->vector[idir]; + } else + p = pressure->compute_scalar(); v = compute_vol(); dhugo = (0.5 * (p + p0 ) * ( v0 - v)) / force->nktv2p + e0 - e; + dhugo /= tdof * boltz; + return dhugo; } + +/* ---------------------------------------------------------------------- + Compute shock velocity is distance/time units +------------------------------------------------------------------------- */ + +double FixNPHug::compute_us() +{ + double v,p; + double eps,us; + + temperature->compute_vector(); + + if (uniaxial == 1) { + pressure->compute_vector(); + p = pressure->vector[idir]; + } else + p = pressure->compute_scalar(); + + v = compute_vol(); + + // Us^2 = (p-p0)/(rho0*eps) + + eps = 1.0 - v/v0; + if (eps < 1.0e-10) us = 0.0; + else if (p < p0) us = 0.0; + else us = sqrt((p-p0)/(rho0*eps)); + + return us; +} + +/* ---------------------------------------------------------------------- + Compute particle velocity is distance/time units +------------------------------------------------------------------------- */ + +double FixNPHug::compute_up() +{ + double v; + double eps,us,up; + + v = compute_vol(); + us = compute_us(); + + // u = eps*Us + + eps = 1.0 - v/v0; + up = us*eps; + + return up; +} + +// look for index in local class +// if index not found, look in base class + +double FixNPHug::compute_vector(int n) +{ + int ilen; + + // n = 0: Hugoniot energy difference (temperature units) + + ilen = 1; + if (n < ilen) return compute_hugoniot(); + n -= ilen; + + // n = 1: Shock velocity + + ilen = 1; + if (n < ilen) return compute_us(); + n -= ilen; + + // n = 2: Particle velocity + + ilen = 1; + if (n < ilen) return compute_up(); + n -= ilen; + + // index not found, look in base class + + FixNH::compute_vector(n); + +} + +/* ---------------------------------------------------------------------- + pack entire state of Fix into one write +------------------------------------------------------------------------- */ + +void FixNPHug::write_restart(FILE *fp) +{ + int nsize = 3; + + // Add on the base class size + + int nsizetot = nsize + FixNH::size_restart(); + + double *list; + memory->create(list,nsize,"nphug:list"); + + int n = 0; + + list[n++] = e0; + list[n++] = v0; + list[n++] = p0; + + if (comm->me == 0) { + int sizetot = nsizetot * sizeof(double); + fwrite(&sizetot,sizeof(int),1,fp); + fwrite(list,sizeof(double),nsize,fp); + } + + memory->destroy(list); + + // Write the base class data without size + + FixNH::write_restart_nosize(fp); + +} + +/* ---------------------------------------------------------------------- + use state info from restart file to restart the Fix +------------------------------------------------------------------------- */ + +void FixNPHug::restart(char *buf) +{ + int n = 0; + double *list = (double *) buf; + e0 = list[n++]; + v0 = list[n++]; + p0 = list[n++]; + + e0_set = 1; + v0_set = 1; + p0_set = 1; + + // Call the base class function + + buf += n*sizeof(double); + FixNH::restart(buf); + +} + +/* ---------------------------------------------------------------------- */ + +int FixNPHug::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0],"e0") == 0) { + if (narg < 2) error->all("Illegal fix nphug command"); + e0 = atof(arg[1]); + e0_set = 1; + return 2; + } else if (strcmp(arg[0],"v0") == 0) { + if (narg < 2) error->all("Illegal fix nphug command"); + v0 = atof(arg[1]); + v0_set = 1; + return 2; + } else if (strcmp(arg[0],"p0") == 0) { + if (narg < 2) error->all("Illegal fix nphug command"); + p0 = atof(arg[1]); + p0_set = 1; + return 2; + } + + return 0; +} diff --git a/src/SHOCK/fix_nphug.h b/src/SHOCK/fix_nphug.h index 37ca8451ea..ee6f5b2ecf 100644 --- a/src/SHOCK/fix_nphug.h +++ b/src/SHOCK/fix_nphug.h @@ -30,20 +30,27 @@ class FixNPHug : public FixNH { ~FixNPHug(); void init(); void setup(int); - + int modify_param(int, char **); + void write_restart(FILE *); + void restart(char *); + private: class Compute *pe; // PE compute pointer void compute_temp_target(); + double compute_vector(int); double compute_etotal(); double compute_vol(); double compute_hugoniot(); + double compute_us(); + double compute_up(); char *id_pe; int peflag; int v0_set,p0_set,e0_set; - double v0,p0,e0; - int direction; + double v0,p0,e0,rho0; + int idir; + int uniaxial; }; } From 2d099c8e7c58f4cdfdcca5f7f84457e8e65ef651 Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 02:45:31 +0000 Subject: [PATCH 097/246] Added example of nphug git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6920 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- examples/prd/in.prd | 4 +++- examples/reax/in.reax.rdx | 7 +++++-- examples/reax/in.reaxc.tatb | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/prd/in.prd b/examples/prd/in.prd index e6e1ed6bf5..09a6fd850b 100644 --- a/examples/prd/in.prd +++ b/examples/prd/in.prd @@ -3,6 +3,8 @@ # run this on multiple partitions as # mpirun -np 4 lmp_g++ -partition 4x1 -in in.prd +#log none + units metal atom_style atomic @@ -72,7 +74,7 @@ neigh_modify every 1 delay 10 check yes # equilibrate -run 1000 +run 100 # only output atoms near vacancy diff --git a/examples/reax/in.reax.rdx b/examples/reax/in.reax.rdx index 053546577e..7f3b8c0e67 100644 --- a/examples/reax/in.reax.rdx +++ b/examples/reax/in.reax.rdx @@ -32,11 +32,14 @@ neigh_modify every 10 delay 0 check no fix 1 all nve -thermo 10 +thermo 1 thermo_style custom step temp epair etotal press v_eb v_ea v_elp v_emol v_ev v_epen v_ecoa v_ehb v_et v_eco v_ew v_ep v_efi v_eqeq timestep 1.0 -dump 1 all atom 10 dump.reax.rdx +#dump 1 all atom 10 dump.reax.rdx +dump 1 all custom 1 dump.reax.rdx id type q xs ys zs + +reset_timestep 1000 run 100 diff --git a/examples/reax/in.reaxc.tatb b/examples/reax/in.reaxc.tatb index 0c959f30fe..b4cdcaa13e 100644 --- a/examples/reax/in.reaxc.tatb +++ b/examples/reax/in.reaxc.tatb @@ -40,5 +40,7 @@ timestep 0.0625 dump 1 all custom 100 dump.reax.tatb id type q x y z +reset_timestep 1000 + run 25 From 7ea78551d224097506c96b7019d28326b04aff90 Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 02:47:28 +0000 Subject: [PATCH 098/246] Removed some stuff git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6921 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- examples/hugoniostat/in.nphug | 159 ++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 examples/hugoniostat/in.nphug diff --git a/examples/hugoniostat/in.nphug b/examples/hugoniostat/in.nphug new file mode 100644 index 0000000000..38cc5b7094 --- /dev/null +++ b/examples/hugoniostat/in.nphug @@ -0,0 +1,159 @@ +# This script reproduces the damped and undamped +# stress trajectories in Fig. 1 in +# Ravelo, Holian, Germann, and Lomdahl, PRB 70 014103 (2004) + +units lj +boundary p p p + +atom_style atomic + +# Set up FCC lattice with z axis along <110> + +lattice fcc 1.4142136 & + orient x 0 0 1 & + orient y 1 -1 0 & + orient z 1 1 0 + +region mycell block 0.0 5.0 0.0 5.0 0.0 5.0 units lattice +create_box 1 mycell +mass * 1.0 +create_atoms 1 box + +# Using units of Rmin, so sigma = 2^-1/6 = 0.8908987 + +pair_style lj/cubic +pair_coeff * * 1.0 0.8908987 + +fix 3 all box/relax aniso 0.0 vmax 1.0e-4 nreset 100 + +thermo 100 +thermo_style custom step temp pe etotal pxx pyy pzz lx ly lz + +min_modify line quadratic +minimize 0.0 1.0e-6 10000 100000 + +# Define initial velocity + +velocity all create 0.01 87287 mom yes rot yes dist gaussian +write_restart restart.equil + +# Start Run #1 + +log log.nodrag + +clear +read_restart restart.equil + +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes +timestep 0.001 +reset_timestep 0 + +# Pzz = 40.0, drag/damping term off + +fix myhug all nphug temp 1.0 1.0 1.0 z 40.0 40.0 70.0 drag 0.0 tchain 1 pchain 0 + +# Specify reference state from paper, times 1000 atoms + +fix_modify myhug e0 -6334.0 p0 0.0 v0 680.73519 + +# Add fix energy to ouput etotal + +fix_modify myhug energy yes + +# Define output + +variable dele equal f_myhug[1] # energy delta [temperature] +variable us equal f_myhug[2] # shock velocity [distance/time] +variable up equal f_myhug[3] # particle velocity [distance/time] +variable pzz equal pzz # axial stress +variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable time equal dt*step + +thermo 10 +thermo_style custom step temp ke epair etotal pzz v_tau lz f_myhug v_dele v_us v_up + +fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (no drag)' + +run 10000 + +# Start Run #2 + +log log.drag + +clear +read_restart restart.equil + +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes +timestep 0.001 +reset_timestep 0 + +# Pzz = 40.0, drag/damping term on + +fix myhug all nphug temp 1.0 1.0 1.0 z 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 + +# Specify reference state from paper, times 1000 atoms + +fix_modify myhug e0 -6334.0 p0 0.0 v0 680.73519 + +# Add fix energy to ouput etotal + +fix_modify myhug energy yes + +# Define output + +variable dele equal f_myhug[1] # energy delta [temperature] +variable us equal f_myhug[2] # shock velocity [distance/time] +variable up equal f_myhug[3] # particle velocity [distance/time] +variable pzz equal pzz # axial stress +variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable time equal dt*step + +thermo 10 +thermo_style custom step temp ke epair etotal pzz v_tau lz f_myhug v_dele v_us v_up + +fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (no drag)' + +run 10000 + +# Start Run #3 + +log log.nhchains + +clear +read_restart restart.equil + +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes +timestep 0.001 +reset_timestep 0 + +# Pzz = 40.0, drag/damping term off, Nose-Hoover chains + +fix myhug all nphug temp 1.0 1.0 1.0 z 40.0 40.0 70.0 + +# Specify reference state from paper, times 1000 atoms + +fix_modify myhug e0 -6334.0 p0 0.0 v0 680.73519 + +# Add fix energy to ouput etotal + +fix_modify myhug energy yes + +# Define output + +variable dele equal f_myhug[1] # energy delta [temperature] +variable us equal f_myhug[2] # shock velocity [distance/time] +variable up equal f_myhug[3] # particle velocity [distance/time] +variable pzz equal pzz # axial stress +variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable time equal dt*step + +thermo 10 +thermo_style custom step temp ke epair etotal pzz v_tau lz f_myhug v_dele v_us v_up + +fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (no drag)' + +run 10000 + From 8280970bee04c6d03889979472b2bff2c303109c Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 18:35:10 +0000 Subject: [PATCH 099/246] Tweaked fix nphug restart git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6923 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 39 +++++++++++++++++++-------------------- src/SHOCK/fix_nphug.h | 3 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 02e744cc9c..7fb233edc6 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -374,38 +374,37 @@ double FixNPHug::compute_vector(int n) } /* ---------------------------------------------------------------------- - pack entire state of Fix into one write + pack restart data ------------------------------------------------------------------------- */ -void FixNPHug::write_restart(FILE *fp) +int FixNPHug::pack_restart_data(double *list) { - int nsize = 3; - - // Add on the base class size - - int nsizetot = nsize + FixNH::size_restart(); - - double *list; - memory->create(list,nsize,"nphug:list"); - int n = 0; list[n++] = e0; list[n++] = v0; list[n++] = p0; - if (comm->me == 0) { - int sizetot = nsizetot * sizeof(double); - fwrite(&sizetot,sizeof(int),1,fp); - fwrite(list,sizeof(double),nsize,fp); - } + // call the base class function - memory->destroy(list); + n += FixNH::pack_restart_data(list+n); - // Write the base class data without size + return n; +} - FixNH::write_restart_nosize(fp); +/* ---------------------------------------------------------------------- + calculate the number of data to be packed +------------------------------------------------------------------------- */ +int FixNPHug::size_restart() +{ + int nsize = 3; + + // call the base class function + + nsize += FixNH::size_restart(); + + return nsize; } /* ---------------------------------------------------------------------- @@ -424,7 +423,7 @@ void FixNPHug::restart(char *buf) v0_set = 1; p0_set = 1; - // Call the base class function + // call the base class function buf += n*sizeof(double); FixNH::restart(buf); diff --git a/src/SHOCK/fix_nphug.h b/src/SHOCK/fix_nphug.h index ee6f5b2ecf..47ef8d1b5a 100644 --- a/src/SHOCK/fix_nphug.h +++ b/src/SHOCK/fix_nphug.h @@ -31,7 +31,8 @@ class FixNPHug : public FixNH { void init(); void setup(int); int modify_param(int, char **); - void write_restart(FILE *); + int pack_restart_data(double *); // pack restart data + int size_restart(); // return size void restart(char *); private: From 3da41b83f917dcacd269470fcac899941d933c09 Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 19:15:20 +0000 Subject: [PATCH 100/246] Finished changes to fix nphug docs git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6924 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/fix_nphug.jpg | Bin 0 -> 12282 bytes doc/Eqs/fix_nphug.tex | 9 ++++++++ doc/fix.txt | 1 + doc/fix_nphug.html | 49 +++++++++++++++++++----------------------- doc/fix_nphug.txt | 41 ++++++++++++++++------------------- 5 files changed, 50 insertions(+), 50 deletions(-) create mode 100644 doc/Eqs/fix_nphug.jpg create mode 100644 doc/Eqs/fix_nphug.tex diff --git a/doc/Eqs/fix_nphug.jpg b/doc/Eqs/fix_nphug.jpg new file mode 100644 index 0000000000000000000000000000000000000000..beed5ed5c9852b5b5c3cacae549113decb151b16 GIT binary patch literal 12282 zcmdUUcU)7=y6#Hoy@P-llqwK)kY8s#b*a12~ z3gB{d_V>{=F}Vu-r)hrz0DA&}QTXq^{?lszaRG~qtG_bRuAjt_{Tzn`=Ffdd5bhu_%!FZ}g4cKQqB{?xf)rUd|GQNK5=bQKH~t7>QKx_C$Ne9$qodQ``gC-3 z{~P{`3)m9;!`cXcpWBWhe}4SmydZA}fb;by{hoDtS8wy{;GGrBrvWVh0eAzh01|Kn z_`x;T27o)R!60V<&_ely_#xaq?(l1ZtK=%dZ{Y1LDZwu*EhF>0`2U;q+dlsq><^DW zb_Zcy`1`XEkgEnr2&(hQoZ&G?vhEc{-zM!n6Y@-~eT%z2gqN3ua5~sREWlZHrb%!d3>N(XL zDh$;K)iM=9Z8)|{hGR!dW3qF`iO>^Mu1Lza!OX%C^r|5SX7#M^ZG#IQI?l2@WlrnTO%rX!d*%&1m4H#V*(TrJ) zb&Mm7+e|b}LQI-W_DrEn=}gs3Lrj~@G|a-xTFj2j5zJZ44a}3wdn{}$GAza{NS1h( z*DQT3-&v_xg;{l2U05Hm7O-}*F0qlZ39xCgIkQEv6|!}+EwfXyi?AE8d$Px|m$MJD z<2YD3qFZ=Go+B=T+f#=8fg8;>DhZo)$Z8 zb~@~I!Re2u_xR56>GApSJ?HD>+dRX0M&pd$DKWWR{w0k*}SuZXOGT_oHIWcd9L!@i~y~`1pzmKRDliwoFGilNHAQmOb{zX zBXmK?LnuS2SLi@kMA%aJp>VzMcac*f1|p#%Wg=fi8AR1ZeMR#{$Ierpzi{5`{EPFS z#h_veVjf~yVngCkaYb>2_zUr22?~je65bN|5|eOxxF$RhUIt%~e8iimmDwUU7A2HDFHEmZ zpF-bIKS_VmfX~3$pws|&Md`}jD_w^4hSv=<4HvJ9UG=-#XaqI7Vw7U^^_tK%?`!qO zfU$vbit&tzh>5RBlPRUCiD{PUikXaAxLNOYw(AbpUtiz9arwrR8`I{Z<^kp%7EBhl z7Nr&kmfDudmh)CpR(GuiZt~nj+@9dVi#=JXU}7Q z+rGtt$-&W~`WD44%UiE+5gm;k^Bwn`44kr^aL!uJ8O|Fn8ZN0WYp$1ElU-NcF1aPU zeRsd)p5ngdq3)6Hv5C+^WFqjM`kuL-2VTZrC0?Z4mbWXB)W}=N25(kxFYhkY8B{Q8 z*hkza#%JDF**DD>=V$0w><{s`^M8Mb9TWl|14IL&0~P|+04! zLLP^#hU$hEg^`CjhjoOX4Zk10a98tgUIZkA3VbV!U&F ze}YWHvjkG2TjJmo#V0vWDW7^jok&todX>zQ9Gbk8Vw6&s%AXpW`ZLWTtuI|ZJvW0k zBOqh`+0|$7p9?;J`ka{QkvX1qIjb`JboS%ygBLC@MshTADsuU9<8lvQB3^#U)61*N z7tT*FpezV1SShq9>@B)bR9eha99Mi?;$1TT%IsBFsZwd_>(j5FltIe^%GTc4zWH3P zUH-lTUXfSHSsC{hcpLC`{oSp16IF&)9n}}AD{6#lvTNCDW9uMwA$7QVkNWxdH{TC8 zTxsZNRB5bjl58qzKHHqt!qM`imA3UkD+v>d*=zG@+iZ7lU+Qq^nC`Ud9P2Xe8tgXg z{?Mb_)7h)pi}`TrLvx>UUqk!{FMLMv1hV3yN}#II*2836JGtg@T>RG@^JMi zh)6|zc6|Q0@x<`tD+x&=`8fJH{?P(t;1%lT1^_=w0D$2p0I+=q09wYs^y8lzkiRr9 zh<~fF-}!g?U+`ZV^G}H)02H(VfF+o(fI0gf00@DZ4FCWW4FI^&20-QH{+7X~zmvb4 zoa`R}p$9c4B{_+-n+^b=ItPx=l1NAGB+_vQsB`lHpi}2B-TJ#WC8%|iWuXA+Rfj~& zy+7^$;X+yf?&$<0KyF4xfEZXn4NyQ>f!~b(aDwoF8t5-3S0KE9!)6fC|5*nL01pws zZ?W{7EvUu+ByfN6=l5TC=u7Co)qteEB>OiE82zqGng(?$6axAEg@Ru&kx`KSPL$;2 zWE51CpeO)U0~IwL4HY#lH63(}mC>YRGj*go=gTg8KPit|;PSh64zppLpq!ImBn>Sm*C}ou zAz=~G^J4M}ib@wQDr;%$=<4YkT)BS3+`L19sG$*a=WRn;}Mb@lHX8aq0>x_f#*^!1O7j*U-Dewo59EG~Up zURnLVwvPX?`*Uyqfbi?^H!lc4_7|_x0wBn*xz|!0eUhB zxOikNfI4tY%#RfX{wX&PEtYJtkpODT9t=5A6?ZN6L;&v)_p$y!IxY`M`LJNR#w*~} z*S>dyWS{6|F0>oOunFp0QXAND6#scw__D)%1vnPjwkmXny9JMHDPggTuNO)K=b=+iloXe9M2w~|09uAN!jYpeh>h7#Js{hK zb{;+dHiw=NccdMD9*63zjD*oN8{uIcnUitya8wUhqjzb(jm-<5o)eY6H%mrZCiNjD z&!#WGME;0X;e5(cvpbkkS2$mU7!0pJvBE0m8s6+ju2=S_ukl>Zs4nHM$&6j8ULOrg zX#Ad^p7?dBNws8=sz?1X8gg>#WGEfYq^3f6xcG1jvRH1YSvL{RgPG!*;Mr=fq@M6D ziNt<1c6Udy*$BeY)RO3F;#)6=Js(aBT>FWSk$L9n+n= zco1JcvCZP>q+OU`t}`^$a<#nqMHU_Near90*twooB^=Y{(V`({s1MfqTq5dPiU z1}_!;7+x^>UQ*SUv9G5AD^->NCrh24n=tQfX$8ufTaG8bwDS6iAwJ2LTXD841?5bW@5W|)au^(cFxllJOy z)Cyup!A>~LFzi?vvFvA$Fq_3AU7q(LT&k0GRkA07I=9@f9~Y}5rDElb%GWbd(XI3$ zY78T9-c<0wqep-$sywpko$G*yX-L$T??v+qpK04XD$rC6OJn* z3=VZpaEV9pZ6K`8%gd+p+647NQSc{%RJGyG$(H*{@6{NN-(V1PR2!XrV-?MgC4`Y~ z?y1ZTL(K4PxO29*;MS3STB+9kwjVP0WOS6a%Eg{++FkmU_06DVFIDLLVOg2gb88wf zv@7JMWi|dX5S^||Jj^i%!^z2UX+Z8n2LR*YzM>j-OPLnZcgRV-T$FfBn+?2JCV~w*zg&*>E|6>HZUJP_I2dJ|nJK^Zb~1 zc>rZq7@DE1S{5-;Wj(FADj_<+Ys?Rq>lp!JI}~sZQ$zb)_=#K+Kyiw&wup`^b){-= zAR?WYa;et(mrEvUdxs^;MVcF+7S}1tG)}HwyO$Ls=Pa$!sWKnbQ^~OoV{T;+&bo@X(Ip21=H+^{g(vHsPoJW%F_Om9LoXc3#xKe6| z#c$F3Gdgw$%|$`N`v#s_h_R(|J&yd;%*le4Wc#GpQJearnuY@;M;kHZI7?OGNFNb; zH@7RRlE=EU_zD<1RF>d>Vh8Z63K0~zBRlU?#R>cXR41tx)Cs~nohXXnGNXw*cGs6w zGcwJ`ET6)6depgQr{$C02e3{Ly>7lPe8cS`OHz#1dGgqPWlWgkr5Xtm&~8wKPfR29U26sw@wwmb)CQsW? zCRDKWPMnd)eYKat1(p{&FnnIGyMFV-#bp;=t=wJ_h2p&I^UchJ_`BH*B}S zn!;=hH^LYTMzUhZ{Y7?{mr+E;6npQ%zOQR1(rb-Fn<03%`JH&Z1Xa_;yHeN3C0hA{ z2kipa6_sm(Mw&wd^FOzr4#eB*y!wP z24@|fw>d~}ALcq_qNC8%j|g`c=2!`X4oqKqDH4;sN_EsqUp?x`uf*=Dyc#i(mL0LR zg?%f8tC)O7*H!MRe8~68Ln4KqH>6YKY>VDV?vO$G4SqX&{(x(<7L*SdI-!U@${j@oGPyK%Srw`dkSJFiL0NQTb%<}1fSh^dpV>%cEGCMYWrG7ncbRFQdEqZ`AqgZV>*|+-@jR`%SC#1 zqZcOT=+wVU;U`G|)58SJFW;N;W0@|xS4_?9jPuKOZ5EBUnjG^$@4gnH5^S?*xh1eD zMM*GRSb6*si%?^%!FH3-eDo5 zb1t?z;Hm9#Dj_7tVRpe_z=RPaW zyd-gFb-Z?nqVE+!#AHl(#Yh*)WzsN`xjcBy+TrbEgTCcYp|H(&F9`#e34Db^M>@7O zITt2)kj~b1T$fiE&V@a3&FiC8T5)P$n|H#K~@HycWGv8g;Iq8zK*l3AUafe;#hnVlJFSmq$E z=5@R-^AlAxXx(wI<=UbYT2N877#G?sf4>xzf7}-j2Mc`KF)gI$I&=hl? zq1VbPX9!QaGqA|nJdU(OyMf}O+SW9`xYLWXr#`i(rm^a)rnk)`1fTEL-BKzd0qKVq zrL?EF_pQHRAIx0zuf0=Sdr)m8m1RM6NY~r+2gTmOL%AU+2<`Fc&!8T4ta=9qQgP>dtDs>; z&*AG2`y^oMNDj(!s@3J{NswDm=)!1d;hQeYp0x zI5+eF+##i%aq;=8DqS;N<|2{6?s|_rf7N3}O*)(%9hZXG;ffFUT`+!2194zlH}t4i z>E9LgnDe!3zSFa^SMf$i&#V9;Sn<VElP_X zicjeNiJ#UM#3?qgas|>hz1WO=*~jg6R^!`Kh{9&Y0(qrLUqouNJtRnmJ(#S z7Zbg>;W=(^Cmd(jPxCiq&MrVChk1jp9%mOm#~y69g_-i1@Dl66FEJi zv_sp_p#Y4A1mKcDIZXH@R3g6qVsdY?;$V2%OVGgI{zxSRIXQ{S#B>K9%O2XP->Ax* zzV4+G=auSF6l+$ITtF{dl|#+{RCB}1fi|3MVJI?}@nL;4{@1B2OsM!>0(wB;Y|J zsQP<6C{qw5z?uYfO1iM&D z!A$IGrxacA!^QOIB^$z$16!~kcBNi=CIsLP_h=$?FuvY9v$A;tO8U%h^`` z^V&NRwT}~8sR?XtjdiuIIM{+)xp0Q(frHDFP9F27Ys}vK2J&7!J~RVwPY2}tn>K&j zZ^En+Xyt#EUlXs(%~*2Af^rp(SzTm0BB=K?7zxa;-V0a93-9(QbHy}^yDxsy(3cE& zbo-^@8nHXt1uo6o7f@SA@1M@B&3IW-O_9I`#!t87d=hYLj)NFL2sn}r_R*V<89O%_ ze)d(ciq1Pc<#UCMAyqa#8LNVf59gH&^l1#(3Qk*Mh=RvYPME{B2|-00_HxHrt!D`0 zrejXKuEPPw^d6(LRxa6sm7YQm>ZJ7zPSG!2b! zUix%q&bH?5n5sxI?=$$Srl7rh28-P%UV&R|312F;{sUt#7ooa#O?Jk^o%?)|P_=Rt zuD&Cg=z2!IDOM$yL#OZsBX&EiKJB&y)>Qu8wDw2md;J?UX~X74N2-tkYG=B!f1HVs zpnonrv5!XT;#W!1O0VLK}8%5`jL`fPQ}jQ+AoiP=PbkjKv-dU?w=aVqdO^x z^dul(1_!!54WBv*i2qFW@BGy-M}?p=4~tbhJFNTzsFC-*|I^q~`0vO1--s<{$2BGRlK2Q#7{$q8 zzM-9eZwlJ+DnMHy%C=wtA2(QV=eUQ;WitEo?_G zsK*4>HAX}&yijJ4GODTkGVq2DEE+so`=|99370$0Ryz~UIW8&H${5Vl zp2ODC6!#%#Np~3jMkrG?=F1Mf=S@FI`x3t?EI_^ybZ>Y@|5ioo?!+{cMXuM0%JIH~ z-&sQMksiTvUSaSBSJ&f!FLUNM&&(aEcVc5+Q^&tVt_;qa!VbIJ?lv{_`1tm%In+;f z+Id;jRK0D$C%tdYQSo??Lpgcw@^-tWf6LPw+yW9^qNkGq;l`bK7zJ$c8#b(a33fX8 z`X*Gvvhy$*3m^Q^+|Q%*)e^-g)6n9TI->5vedmSs$X2U3(YcAUT5wjU2gBQ`IKfb* z!%Sb=L;c}{@FUa?dEJ4rbL9{T_(HZH@EPNUVvQI+xkz~YD*SRIuC4_ybpy8=jdaGZ z)T0;@bBoVe8N;8);IEzu_-Xy1seu1U3OR)d#*>I_!k1@s!odSE_XMd1(awu@T3w-8GsXf#VPU93<3g;~>VW(tV*-5aQGEZ$6u{(T#6^|6SyC2@J7`H8 z^fcBkZ(t!7V?#{#oKq4f0n?4shNH(Z7}SSW){{>;;-e=rp0iSfxS$10+~H2g+{5pA z0ZgpHGjMlQRhwY4j=^#QXYlNg5NBh_u}`X{yDgySQZNv9skU5?I64n=4+O8j1hLAtmAJBWhS!L-09M1Uo&3gKp+~8ZXJCa!P zBcbm{mQ!64NI}ufV#VZ&lp|rH@u)f&?PDXP-c6{=xXuqf&Yc?YeO=U*vf=Z^Y7K>C zOyS6ye&nPT<{uP184*@D@#6u1-%9slE}i=P3v>NMBj?p&#QwCpk_V(9fSeh<#~CPU75@T^E}=#~!#+*Z1RFDW!^?-SDv z!VYeytyOWXSx&&PU}gi$P*J3oy!oNKyf8=6!@#4!$s|7Y`WKT{(K)ZOLkEWz#4_gT zsBcr^@ukoR^^vax2Z6Y(pGQIq;VW|geF;hdem@ePGF-UFjELAhCtalY%* zLDo43^OaboHZ-dO!p-A<@D z_|MFN{VDvDEf~11`%IX5MN}J6RWG_p)CAw~3s&I@Ej1IunFr>%W@FbLWmx)V1=!rO zc4^dN8+ztK6=TNqI@o>R1~0YgKHmcCj^G*HQTu&#dJy^MgqNVCftyLFd&u~rIHQhj za3Cbq%s?>A=Aw|lSajkrr|1C+aW`l`;5hwfWelups3R8$H>w(Gz8->`zA};|xdS)z zJuY&GicIIvGWLbH3&!zxLcc|dU#TfIk6#GuS(hq6^v(1RC5g}JoVT%26bo=Q=s{T9 zRMdHj>;614UPoq!4FQoaSFL z-Hg4PA4QeowKAF1;|CLAodSk|us93WmGZwDa&#uk9{xubSM*o-xzO zkk92qin_Fg$x+E#x-UQbe$J`wuhxFcToLVZExI+hS>QOrX66&1WZOJ98`?1a zx}~w{2zyEDw4K5gwgf3P2O%$=OJ*Y*=EQn0d&@lrcGH_Y(f`w_|INAoU%10aQ~v`b C-pi2y literal 0 HcmV?d00001 diff --git a/doc/Eqs/fix_nphug.tex b/doc/Eqs/fix_nphug.tex new file mode 100644 index 0000000000..4e162b69b7 --- /dev/null +++ b/doc/Eqs/fix_nphug.tex @@ -0,0 +1,9 @@ +\documentstyle[12pt]{article} + +\begin{document} + +$$ +T_t - T = \frac{\left(\frac{1}{2}\left(P + P_0\right)\left(V_0 - V\right) + E_0 - E\right)}{N_{dof} k_B } = Delta +$$ + +\end{document} diff --git a/doc/fix.txt b/doc/fix.txt index 23a478c496..428b377fa1 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -188,6 +188,7 @@ list of fix styles available in LAMMPS: "nph"_fix_nh.html - constant NPH time integration via Nose/Hoover "nph/asphere"_fix_nph_asphere.html - NPH for aspherical particles "nph/sphere"_fix_nph_sphere.html - NPH for spherical particles +"nphug"_fix_nphug.html - Constant-stress Hugoniostat integration "npt"_fix_nh.html - constant NPT time integration via Nose/Hoover "npt/asphere"_fix_npt_asphere.html - NPT for aspherical particles "npt/sphere"_fix_npt_sphere.html - NPT for spherical particles diff --git a/doc/fix_nphug.html b/doc/fix_nphug.html index e4ad3a3f2e..5d4b56cbce 100644 --- a/doc/fix_nphug.html +++ b/doc/fix_nphug.html @@ -45,9 +45,9 @@ keyword = temp or iso or aniso or tri or x or

    Examples:

    -

    fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0 +

    fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0
     fix myhug all nphug temp 1.0 1.0 10.0 iso 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 
    -

    +

    Description:

    This command is a variant of the Nose-Hoover @@ -61,8 +61,8 @@ jump conditions for steady shocks.

    The compression can be performed either -hydrostatically (using keyword iso, aniso, or tri) or uniaxially -(using keywords x, y, or z). In the hydrostatic case, +hydrostatically (using keyword iso, aniso, or tri) or uniaxially +(using keywords x, y, or z). In the hydrostatic case, the cell dimensions change dynamically so that the average axial stress in all three directions converges towards the specified target value. In the uniaxial case, the chosen cell dimension changes dynamically @@ -72,34 +72,30 @@ other two cell dimensions are kept fixed (zero lateral strain).

    This leads to the following additional restrictions on the keywords:

    -

    One and only one of the following keywords should be used: iso, aniso, tri, x, y, z, -

    -

    The specified initial and final target pressures must be the same. -

    -

    The keywords xy, xz, yz may not be used. -

    -

    The only admissible value for the couple keyword is xyz, -which has the same effect as keyword iso -

    -
    • The temp keyword must be used in order to specify the time constant for -
    • kinetic energy relaxation, but initial and final target temperature values -
    • are ignored. +
      • One and only one of the following keywords should be used: iso, aniso, tri, x, y, z +
      • The specified initial and final target pressures must be the same. +
      • The keywords xy, xz, yz may not be used. +
      • The only admissible value for the couple keyword is xyz, which has the same effect as keyword iso +
      • The temp keyword must be used to specify the time constant for kinetic energy relaxation, but initial and final target temperature values are ignored.

      Essentially, a Hugoniostat simulation is an NPT simulation in which the user-specified target temperature is replaced with a time-dependent target temperature Tt obtained from the following equation:

      -

      Tt - T = (0.5*(P+P0)(V0-V)+E0-E)/(Ndof kB) = Delta -

      +
      +

      where T and Tt are the instantaneous and target temperatures, -P and P0 are the instantaneous and reference pressure or axial stress, +P and P0 are the instantaneous and reference pressures or axial stresses, depending on whether hydrostatic or uniaxial compression is being performed, V and V0 are the instantaneous and reference volumes, E and E0 are the instantaneous and reference internal energy (potential plus kinetic), Ndof is the number of degrees of freedom used in the definition of temperature, and kB is the Boltzmann constant. Delta is the negative deviation of the instantaneous temperature from the target temperature. -The values of E0, V0, and P0 are the instantaneous values at the start of +When the system reaches a stable equilibrium, the value of Delta should +fluctuate about zero. +

      +

      The values of E0, V0, and P0 are the instantaneous values at the start of the simulation. These can be overridden using the fix_modify keywords e0, v0, and p0 described below.

      @@ -117,7 +113,7 @@ commands.


      -

      This fix compute a temperature and pressure each timestep. To do +

      This fix computes a temperature and pressure at each timestep. To do this, the fix creates its own computes of style "temp" and "pressure", as if one of these two sets of commands had been issued:

      @@ -130,8 +126,7 @@ compute fix-ID_press all pressure fix-ID_temp

      See the compute temp and compute pressure commands for details. Note that the IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID -+ underscore + "press". For fix nvt, the group for the new computes -is the same as the fix group. For fix nph and fix npt, the group for ++ underscore + "press". The group for the new computes is "all" since pressure is computed for the entire system.

      @@ -157,8 +152,8 @@ a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion.

      The fix_modify e0, v0 and p0 keywords -can be used to define the values of these quantities. Note the -the values for e0 and v0 are extensive, and so must correspond +can be used to define the values of E0, V0, and P0. Note the +the values for e0 and p0 are extensive, and so must correspond to the total energy and volume of the entire system, not energy and volume per atom. If any of these quantities are not specified, then the instanteous value in the system at the start of the simulation is used. @@ -190,8 +185,8 @@ these fixes is "extensive"; the vector values are "intensive". followed by all the internal Nose/Hoover thermostat and barostat variables defined for fix_style npt. Delta is the deviation of the temperature from the target temperature, given by the above equation. -Us and up are the shock and particle velocity correspponding to a steady -shock calculated from the Rh conditions. They have units of distance/time. +Us and up are the shock and particle velocity corresponding to a steady +shock calculated from the RH conditions. They have units of distance/time.

      Restrictions:

      diff --git a/doc/fix_nphug.txt b/doc/fix_nphug.txt index 6bb5664302..6ac59d1e16 100644 --- a/doc/fix_nphug.txt +++ b/doc/fix_nphug.txt @@ -41,7 +41,7 @@ keyword = {temp} or {iso} or {aniso} or {tri} or {x} or {y} or {z} or {couple} o [Examples:] fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0 -fix myhug all nphug temp 1.0 1.0 10.0 iso 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 +fix myhug all nphug temp 1.0 1.0 10.0 iso 40.0 40.0 70.0 drag 200.0 tchain 1 pchain 0 :pre [Description:] @@ -56,8 +56,8 @@ jump conditions for steady shocks. The compression can be performed either -hydrostatically (using keyword iso, aniso, or tri) or uniaxially -(using keywords x, y, or z). In the hydrostatic case, +hydrostatically (using keyword {iso}, {aniso}, or {tri}) or uniaxially +(using keywords {x}, {y}, or {z}). In the hydrostatic case, the cell dimensions change dynamically so that the average axial stress in all three directions converges towards the specified target value. In the uniaxial case, the chosen cell dimension changes dynamically @@ -67,33 +67,29 @@ other two cell dimensions are kept fixed (zero lateral strain). This leads to the following additional restrictions on the keywords: -One and only one of the following keywords should be used: iso, aniso, tri, x, y, z, - +One and only one of the following keywords should be used: {iso}, {aniso}, {tri}, {x}, {y}, {z} The specified initial and final target pressures must be the same. - -The keywords xy, xz, yz may not be used. - -The only admissible value for the couple keyword is xyz, -which has the same effect as keyword iso - -The temp keyword must be used in order to specify the time constant for -kinetic energy relaxation, but initial and final target temperature values -are ignored. :ul +The keywords {xy}, {xz}, {yz} may not be used. +The only admissible value for the couple keyword is {xyz}, which has the same effect as keyword {iso} +The {temp} keyword must be used to specify the time constant for kinetic energy relaxation, but initial and final target temperature values are ignored. :ul Essentially, a Hugoniostat simulation is an NPT simulation in which the user-specified target temperature is replaced with a time-dependent target temperature Tt obtained from the following equation: -Tt - T = (0.5*(P+P0)(V0-V)+E0-E)/(Ndof kB) = Delta +:c,image(Eqs/fix_nphug.jpg) where T and Tt are the instantaneous and target temperatures, -P and P0 are the instantaneous and reference pressure or axial stress, +P and P0 are the instantaneous and reference pressures or axial stresses, depending on whether hydrostatic or uniaxial compression is being performed, V and V0 are the instantaneous and reference volumes, E and E0 are the instantaneous and reference internal energy (potential plus kinetic), Ndof is the number of degrees of freedom used in the definition of temperature, and kB is the Boltzmann constant. Delta is the negative deviation of the instantaneous temperature from the target temperature. +When the system reaches a stable equilibrium, the value of Delta should +fluctuate about zero. + The values of E0, V0, and P0 are the instantaneous values at the start of the simulation. These can be overridden using the fix_modify keywords {e0}, {v0}, and {p0} described below. @@ -112,7 +108,7 @@ commands. :line -This fix compute a temperature and pressure each timestep. To do +This fix computes a temperature and pressure at each timestep. To do this, the fix creates its own computes of style "temp" and "pressure", as if one of these two sets of commands had been issued: @@ -125,8 +121,7 @@ compute fix-ID_press all pressure fix-ID_temp :pre See the "compute temp"_compute_temp.html and "compute pressure"_compute_pressure.html commands for details. Note that the IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID -+ underscore + "press". For fix nvt, the group for the new computes -is the same as the fix group. For fix nph and fix npt, the group for ++ underscore + "press". The group for the new computes is "all" since pressure is computed for the entire system. @@ -152,8 +147,8 @@ a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. The "fix_modify"_fix_modify.html {e0}, {v0} and {p0} keywords -can be used to define the values of these quantities. Note the -the values for {e0} and {v0} are extensive, and so must correspond +can be used to define the values of E0, V0, and P0. Note the +the values for {e0} and {p0} are extensive, and so must correspond to the total energy and volume of the entire system, not energy and volume per atom. If any of these quantities are not specified, then the instanteous value in the system at the start of the simulation is used. @@ -185,8 +180,8 @@ The vector stores three quantities unique to this fix (Delta, Us, and up), followed by all the internal Nose/Hoover thermostat and barostat variables defined for "fix_style npt"_fix_nh.html. Delta is the deviation of the temperature from the target temperature, given by the above equation. -Us and up are the shock and particle velocity correspponding to a steady -shock calculated from the Rh conditions. They have units of distance/time. +Us and up are the shock and particle velocity corresponding to a steady +shock calculated from the RH conditions. They have units of distance/time. [Restrictions:] From d34543f2a67efb187cfb27df71d2621c8a86ee43 Mon Sep 17 00:00:00 2001 From: athomps Date: Fri, 2 Sep 2011 19:16:43 +0000 Subject: [PATCH 101/246] Tweaked input file git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6925 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- examples/hugoniostat/in.nphug | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/examples/hugoniostat/in.nphug b/examples/hugoniostat/in.nphug index 38cc5b7094..a41c38d2b1 100644 --- a/examples/hugoniostat/in.nphug +++ b/examples/hugoniostat/in.nphug @@ -1,6 +1,16 @@ -# This script reproduces the damped and undamped -# stress trajectories in Fig. 1 in +# This script reproduces stress trajectories from Fig. 1 in # Ravelo, Holian, Germann, and Lomdahl, PRB 70 014103 (2004) +# +# Three thermostatting scenarios are visited: undamped (nodrag), +# damped (drag) and Nose-Hoover chain (nhchains). +# +# The axial and shear stress trajectories are printed to the +# file "stress_vs_t.dat". For the damped case, the original figure +# seems to be a plot of 2*tau, rather than tau. +# +# The script also demonstrates how to +# orient a crystal along <110>, +# and how to use the lj/cubic pair style. units lj boundary p p p @@ -24,6 +34,8 @@ create_atoms 1 box pair_style lj/cubic pair_coeff * * 1.0 0.8908987 +# Relax box dimensions + fix 3 all box/relax aniso 0.0 vmax 1.0e-4 nreset 100 thermo 100 @@ -51,7 +63,7 @@ reset_timestep 0 # Pzz = 40.0, drag/damping term off -fix myhug all nphug temp 1.0 1.0 1.0 z 40.0 40.0 70.0 drag 0.0 tchain 1 pchain 0 +fix myhug all nphug temp 1.0 1.0 10.0 z 40.0 40.0 70.0 drag 0.0 tchain 1 pchain 0 # Specify reference state from paper, times 1000 atoms @@ -67,7 +79,7 @@ variable dele equal f_myhug[1] # energy delta [temperature] variable us equal f_myhug[2] # shock velocity [distance/time] variable up equal f_myhug[3] # particle velocity [distance/time] variable pzz equal pzz # axial stress -variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable tau equal 0.5*(pzz-0.5*(pxx+pyy)) # shear stress variable time equal dt*step thermo 10 @@ -107,13 +119,13 @@ variable dele equal f_myhug[1] # energy delta [temperature] variable us equal f_myhug[2] # shock velocity [distance/time] variable up equal f_myhug[3] # particle velocity [distance/time] variable pzz equal pzz # axial stress -variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable tau equal 0.5*(pzz-0.5*(pxx+pyy)) # shear stress variable time equal dt*step thermo 10 thermo_style custom step temp ke epair etotal pzz v_tau lz f_myhug v_dele v_us v_up -fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (no drag)' +fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (with drag)' run 10000 @@ -147,13 +159,13 @@ variable dele equal f_myhug[1] # energy delta [temperature] variable us equal f_myhug[2] # shock velocity [distance/time] variable up equal f_myhug[3] # particle velocity [distance/time] variable pzz equal pzz # axial stress -variable tau equal (pzz-0.5*(pxx+pyy)) # shear stress +variable tau equal 0.5*(pzz-0.5*(pxx+pyy)) # shear stress variable time equal dt*step thermo 10 thermo_style custom step temp ke epair etotal pzz v_tau lz f_myhug v_dele v_us v_up -fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (no drag)' +fix stress all print 10 "${time} ${pzz} ${tau} " screen no append stress_vs_t.dat title '#time pzz tau (Nose-Hoover chain)' run 10000 From 26685383791fdd9ecb9ec407abbcc6edaaf0fd19 Mon Sep 17 00:00:00 2001 From: athomps Date: Wed, 7 Sep 2011 16:55:54 +0000 Subject: [PATCH 102/246] Added changes to FixNH restart git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6933 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_nh.cpp | 58 +++++++++++++++++++++++++++++++++----------------- src/fix_nh.h | 10 ++++++--- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 50d3c4dd79..9d88d8f0fb 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -642,14 +642,14 @@ void FixNH::setup(int vflag) tdof = temperature->dof; // t_target is needed by NPH and NPT in compute_scalar() - // If no thermostat, + // If no thermostat or using fix nphug, // t_target must be defined by other means. - if (tstat_flag) { + if (tstat_flag && strcmp(style,"nphug") != 0) { compute_temp_target(); } else if (pstat_flag) { - // t0 = initial value for piston mass and energy conservation + // t0 = reference temperature for masses // cannot be done in init() b/c temperature cannot be called there // is b/c Modify::init() inits computes after fixes due to dof dependence // guesstimate a unit-dependent t0 if actual T = 0.0 @@ -675,7 +675,7 @@ void FixNH::setup(int vflag) pressure->addstep(update->ntimestep+1); } - // initial forces on thermostat variables + // masses and initial forces on thermostat variables if (tstat_flag) { eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); @@ -687,6 +687,8 @@ void FixNH::setup(int vflag) } } + // masses and initial forces on barostat variables + if (pstat_flag) { double kt = boltz * t_target; double nkt = atom->natoms * kt; @@ -700,7 +702,7 @@ void FixNH::setup(int vflag) if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); } - // initial forces on barostat thermostat variables + // masses and initial forces on barostat thermostat variables if (mpchain) { etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max); @@ -729,9 +731,6 @@ void FixNH::initial_integrate(int vflag) if (tstat_flag) { compute_temp_target(); - eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); - for (int ich = 1; ich < mtchain; ich++) - eta_mass[ich] = boltz * t_target / (t_freq*t_freq); nhc_temp_integrate(); } @@ -828,9 +827,6 @@ void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop) if (tstat_flag) { compute_temp_target(); - eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); - for (int ich = 1; ich < mtchain; ich++) - eta_mass[ich] = boltz * t_target / (t_freq*t_freq); nhc_temp_integrate(); } @@ -1118,6 +1114,28 @@ void FixNH::remap() ------------------------------------------------------------------------- */ void FixNH::write_restart(FILE *fp) +{ + int nsize = size_restart(); + + double *list; + memory->create(list,nsize,"nh:list"); + + int n = pack_restart_data(list); + + if (comm->me == 0) { + int size = nsize * sizeof(double); + fwrite(&size,sizeof(int),1,fp); + fwrite(list,sizeof(double),nsize,fp); + } + + memory->destroy(list); +} + +/* ---------------------------------------------------------------------- + calculate the number of data to be packed +------------------------------------------------------------------------- */ + +int FixNH::size_restart() { int nsize = 2; if (tstat_flag) nsize += 1 + 2*mtchain; @@ -1126,9 +1144,15 @@ void FixNH::write_restart(FILE *fp) if (deviatoric_flag) nsize += 6; } - double *list; - memory->create(list,nsize,"nh:list"); + return nsize; +} +/* ---------------------------------------------------------------------- + pack restart data +------------------------------------------------------------------------- */ + +int FixNH::pack_restart_data(double *list) +{ int n = 0; list[n++] = tstat_flag; @@ -1175,13 +1199,7 @@ void FixNH::write_restart(FILE *fp) } } - if (comm->me == 0) { - int size = nsize * sizeof(double); - fwrite(&size,sizeof(int),1,fp); - fwrite(list,sizeof(double),nsize,fp); - } - - memory->destroy(list); + return n; } /* ---------------------------------------------------------------------- diff --git a/src/fix_nh.h b/src/fix_nh.h index 1a2f44e6cf..79d18a77ef 100644 --- a/src/fix_nh.h +++ b/src/fix_nh.h @@ -31,9 +31,11 @@ class FixNH : public Fix { void final_integrate_respa(int, int); void pre_exchange(); double compute_scalar(); - double compute_vector(int); + virtual double compute_vector(int); void write_restart(FILE *); - void restart(char *); + virtual int pack_restart_data(double *); // pack restart data + virtual int size_restart(); // return size + virtual void restart(char *); int modify_param(int, char **); void reset_target(double); void reset_dt(); @@ -42,7 +44,9 @@ class FixNH : public Fix { int dimension,which; double dtv,dtf,dthalf,dt4,dt8,dto; double boltz,nktv2p,tdof; - double vol0,t0; + double vol0; // reference volume + double t0; // reference temperature + // used for barostat mass double t_start,t_stop; double t_current,t_target,ke_target; From 3e4cee821b37739a5a988062f821b9baa6fca7ca Mon Sep 17 00:00:00 2001 From: athomps Date: Thu, 8 Sep 2011 16:33:05 +0000 Subject: [PATCH 103/246] Removed seed from TAD doc file git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6934 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/tad.html | 6 +++--- doc/tad.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/tad.html b/doc/tad.html index a454bf8671..029b7e2de5 100644 --- a/doc/tad.html +++ b/doc/tad.html @@ -13,7 +13,7 @@

    13.1 Coming attractions

  • R@u{jtFG7NF|fp8Vj@)lOz1= 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

    Syntax:

    -
    tad N t_event T_lo T_hi delta tmax compute-ID seed keyword value ... 
    +
    tad N t_event T_lo T_hi delta tmax compute-ID keyword value ... 
     
    • N = # of timesteps to run (not including dephasing/quenching) @@ -52,8 +52,8 @@

    Examples:

    -
    tad 2000 50 1800 2300 0.01 0.01 event 54985
    -tad 2000 50 1800 2300 0.01 0.01 event 54985 &
    +
    tad 2000 50 1800 2300 0.01 0.01 event
    +tad 2000 50 1800 2300 0.01 0.01 event &
         min 1e-05 1e-05 100 100 &
         neb 0.0 0.01 200 200 20 &
         min_style cg &
    diff --git a/doc/tad.txt b/doc/tad.txt
    index f18edb0676..0cbe980948 100644
    --- a/doc/tad.txt
    +++ b/doc/tad.txt
    @@ -11,7 +11,7 @@ tad command :h3
     [Syntax:]
     
     tad N t_event T_lo T_hi delta tmax compute-ID \
    -seed keyword value ... :pre
    +keyword value ... :pre
     
     N = # of timesteps to run (not including dephasing/quenching) :ulb,l
     t_event = timestep interval between event checks :l
    @@ -41,8 +41,8 @@ keyword = {min} or {neb} or {min_style} or {neb_style} or {neb_log} :l
     
     [Examples:]
     
    -tad 2000 50 1800 2300 0.01 0.01 event 54985
    -tad 2000 50 1800 2300 0.01 0.01 event 54985 &
    +tad 2000 50 1800 2300 0.01 0.01 event
    +tad 2000 50 1800 2300 0.01 0.01 event &
         min 1e-05 1e-05 100 100 &
         neb 0.0 0.01 200 200 20 &
         min_style cg &
    
    From 5406456a9b8d23e1db85ae0d76913541bdac1dad Mon Sep 17 00:00:00 2001
    From: athomps 
    Date: Thu, 8 Sep 2011 16:58:27 +0000
    Subject: [PATCH 104/246] Fixed typo in tad.txt
    
    git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6935 f3b2605a-c512-4ea7-a41b-209d697bcdaa
    ---
     doc/tad.html | 11 +++++++----
     doc/tad.txt  | 12 ++++++++----
     2 files changed, 15 insertions(+), 8 deletions(-)
    
    diff --git a/doc/tad.html b/doc/tad.html
    index 029b7e2de5..08a87fc8bf 100644
    --- a/doc/tad.html
    +++ b/doc/tad.html
    @@ -202,10 +202,13 @@ high-temperature time since entering the current basin, scaled by an
     exponential factor that depends on the hi/lo temperature ratio and the
     energy barrier for that event.
     

    -

    On lines for executed events, with status E, the global event number -is incremented by one, and the timestep, local event number, energy -barrier, t_lo, and delt_lo match the last event with status DF -in the immediately preceding block of detected events. +

    On lines for executed events, with status E, the global event number +is incremented by one, +the local event number and time margin are reset to zero, +while the global event number, energy barrier, and +delt_lo match the last event with status DF +in the immediately preceding block of detected events. +The low-temperature event time t_lo is incremented by delt_lo.

    The NEB statistics are written to the file specified by the neb_log keyword. If the keyword value is "none", then no NEB statistics are diff --git a/doc/tad.txt b/doc/tad.txt index 0cbe980948..adb10fcc3a 100644 --- a/doc/tad.txt +++ b/doc/tad.txt @@ -192,10 +192,14 @@ high-temperature time since entering the current basin, scaled by an exponential factor that depends on the hi/lo temperature ratio and the energy barrier for that event. -On lines for executed events, with status {E}, the global event number -is incremented by one, and the timestep, local event number, energy -barrier, {t_lo}, and {delt_lo} match the last event with status {DF} -in the immediately preceding block of detected events. +On lines for executed events, with status {E}, the global event number +is incremented by one, +the local event number and time margin are reset to zero, +while the global event number, energy barrier, and +{delt_lo} match the last event with status {DF} +in the immediately preceding block of detected events. +The low-temperature event time {t_lo} is incremented by {delt_lo}. + The NEB statistics are written to the file specified by the {neb_log} keyword. If the keyword value is "none", then no NEB statistics are From eea9b8bfe011ca96f6e69734b6aca98b64125479 Mon Sep 17 00:00:00 2001 From: athomps Date: Sun, 11 Sep 2011 22:06:09 +0000 Subject: [PATCH 105/246] Added another tweak to fix_nh.cpp git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6938 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_nh.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 9d88d8f0fb..06a134bc17 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -1580,10 +1580,38 @@ void FixNH::reset_dt() p_freq_max = MAX(p_freq_max,p_freq[4]); p_freq_max = MAX(p_freq_max,p_freq[5]); } + + double kt = boltz * t_target; + double nkt = atom->natoms * kt; + + for (int i = 0; i < 3; i++) + if (p_flag[i]) + omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); + + if (pstyle == TRICLINIC) { + for (int i = 3; i < 6; i++) + if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); + } + + // masses and initial forces on barostat thermostat variables + + if (mpchain) { + etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max); + for (int ich = 1; ich < mpchain; ich++) + etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max); + for (int ich = 1; ich < mpchain; ich++) + etap_dotdot[ich] = + (etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] - + boltz * t_target) / etap_mass[ich]; + } + pdrag_factor = 1.0 - (update->dt * p_freq_max * drag / nc_pchain); } if (tstat_flag) + eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); + for (int ich = 1; ich < mtchain; ich++) + eta_mass[ich] = boltz * t_target / (t_freq*t_freq); tdrag_factor = 1.0 - (update->dt * t_freq * drag / nc_tchain); } From e51d04c730ea1c3a056227869bc85f5cf541bc70 Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 13 Sep 2011 00:28:42 +0000 Subject: [PATCH 106/246] Added warning about box dimesnions git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6941 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix_qeq_reax.html | 4 ++++ doc/fix_qeq_reax.txt | 4 ++++ doc/pair_reax_c.html | 8 +++++++- doc/pair_reax_c.txt | 7 ++++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/doc/fix_qeq_reax.html b/doc/fix_qeq_reax.html index ef970af524..f2b47635e7 100644 --- a/doc/fix_qeq_reax.html +++ b/doc/fix_qeq_reax.html @@ -77,6 +77,10 @@ be used with the start/stop keywords of the run LAMMPS was built with that package. See the Making LAMMPS section for more info.

    +

    This fix does not correctly handle interactions +involving multiple periodic images of the same atom. Hence, it should not +be used for periodic cell dimensions less than 10 angstroms. +

    Related commands:

    pair_style reax/c diff --git a/doc/fix_qeq_reax.txt b/doc/fix_qeq_reax.txt index f57f2f2549..4f45ecefd2 100644 --- a/doc/fix_qeq_reax.txt +++ b/doc/fix_qeq_reax.txt @@ -74,6 +74,10 @@ This fix is part of the USER-REAXC package. It is only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. +This fix does not correctly handle interactions +involving multiple periodic images of the same atom. Hence, it should not +be used for periodic cell dimensions less than 10 angstroms. + [Related commands:] "pair_style reax/c"_pair_reax_c.html diff --git a/doc/pair_reax_c.html b/doc/pair_reax_c.html index c4a27801ee..c3a81e0f98 100644 --- a/doc/pair_reax_c.html +++ b/doc/pair_reax_c.html @@ -258,6 +258,10 @@ use another command that tries to calculate these quantities using this pair style, a warning message will be printed and the quantities will be 0.0.

    +

    This pair style does not correctly handle interactions +involving multiple periodic images of the same atom. Hence, it should not +be used for periodic cell dimensions less than 10 angstroms. +

    Related commands:

    pair_coeff, fix_qeq_reax, @@ -274,7 +278,9 @@ will be 0.0.

    (Chenoweth_2008) Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008).

    -

    :link(Aktulga) (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel + + +

    (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to appear (2011).

    diff --git a/doc/pair_reax_c.txt b/doc/pair_reax_c.txt index 6706ab687f..893ae669aa 100644 --- a/doc/pair_reax_c.txt +++ b/doc/pair_reax_c.txt @@ -254,6 +254,10 @@ use another command that tries to calculate these quantities using this pair style, a warning message will be printed and the quantities will be 0.0. +This pair style does not correctly handle interactions +involving multiple periodic images of the same atom. Hence, it should not +be used for periodic cell dimensions less than 10 angstroms. + [Related commands:] "pair_coeff"_pair_coeff.html, "fix_qeq_reax"_fix_qeq_reax.html, @@ -269,5 +273,6 @@ The keyword default is checkqeq = yes. [(Chenoweth_2008)] Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008). -:link(Aktulga) [(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel +:link(Aktulga) +[(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to appear (2011). From 9f02b4057ba7c7bce0fd5a4366214e0286a791ab Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 13 Sep 2011 00:37:31 +0000 Subject: [PATCH 107/246] Added warning about box dimesnions git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6942 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-REAXC/fix_qeq_reax.cpp | 3 +++ src/USER-REAXC/pair_reax_c.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/USER-REAXC/fix_qeq_reax.cpp b/src/USER-REAXC/fix_qeq_reax.cpp index 6a2bba5d8e..102faab8bc 100644 --- a/src/USER-REAXC/fix_qeq_reax.cpp +++ b/src/USER-REAXC/fix_qeq_reax.cpp @@ -401,6 +401,9 @@ void FixQEqReax::pre_force(int vflag) if (update->ntimestep % nevery) return; if( comm->me == 0 ) t_start = MPI_Wtime(); + if (domain->xprd < swb || domain->yprd < swb || domain->zprd < swb) + error->warning("FixQEqReax cutoff greater than periodic dimension"); + n = atom->nlocal; N = atom->nlocal + atom->nghost; // grow arrays if necessary diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index aaf517f768..d13fef914b 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -27,6 +27,7 @@ #include "fix.h" #include "fix_reax_c.h" #include "memory.h" +#include "domain.h" #include "error.h" #include "reaxc_types.h" @@ -378,6 +379,9 @@ void PairReaxC::compute(int eflag, int vflag) double evdwl,ecoul; double t_start, t_end; + if (domain->xprd < cutmax || domain->yprd < cutmax || domain->zprd < cutmax) + error->warning("PairReaxC cutoff greater than periodic dimension"); + // communicate num_bonds once every reneighboring // 2 num arrays stored by fix, grab ptr to them From d9a1ca64ffb439c28b86d424096d32796731764d Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 13 Sep 2011 20:08:09 +0000 Subject: [PATCH 108/246] Added flag to make only fix_nphug use constant eta_mass git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6943 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 4 ++++ src/fix_nh.cpp | 52 +++++++++++------------------------------ src/fix_nh.h | 2 ++ 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 7fb233edc6..16ba8ffed8 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -36,6 +36,10 @@ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { + // Prevent eta_mass from being updated every timestep + + eta_mass_flag = 0; + // extend vector of base-class computes size_vector += 3; diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 06a134bc17..16005c199a 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -72,6 +72,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) mtk_flag = 1; deviatoric_flag = 0; nreset_h0 = 0; + eta_mass_flag = 1; // turn on tilt factor scaling, whenever applicable @@ -731,6 +732,11 @@ void FixNH::initial_integrate(int vflag) if (tstat_flag) { compute_temp_target(); + if (eta_mass_flag) { + eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); + for (int ich = 1; ich < mtchain; ich++) + eta_mass[ich] = boltz * t_target / (t_freq*t_freq); + } nhc_temp_integrate(); } @@ -827,6 +833,11 @@ void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop) if (tstat_flag) { compute_temp_target(); + if (eta_mass_flag) { + eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); + for (int ich = 1; ich < mtchain; ich++) + eta_mass[ich] = boltz * t_target / (t_freq*t_freq); + } nhc_temp_integrate(); } @@ -1570,48 +1581,11 @@ void FixNH::reset_dt() if (strstr(update->integrate_style,"respa")) dto = 0.5*step_respa[0]; - - p_freq_max = 0.0; - if (pstat_flag) { - p_freq_max = MAX(p_freq[0],p_freq[1]); - p_freq_max = MAX(p_freq_max,p_freq[2]); - if (pstyle == TRICLINIC) { - p_freq_max = MAX(p_freq_max,p_freq[3]); - p_freq_max = MAX(p_freq_max,p_freq[4]); - p_freq_max = MAX(p_freq_max,p_freq[5]); - } - - double kt = boltz * t_target; - double nkt = atom->natoms * kt; - - for (int i = 0; i < 3; i++) - if (p_flag[i]) - omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); - - if (pstyle == TRICLINIC) { - for (int i = 3; i < 6; i++) - if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); - } - - // masses and initial forces on barostat thermostat variables - - if (mpchain) { - etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max); - for (int ich = 1; ich < mpchain; ich++) - etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max); - for (int ich = 1; ich < mpchain; ich++) - etap_dotdot[ich] = - (etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] - - boltz * t_target) / etap_mass[ich]; - } + if (pstat_flag) pdrag_factor = 1.0 - (update->dt * p_freq_max * drag / nc_pchain); - } - + if (tstat_flag) - eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); - for (int ich = 1; ich < mtchain; ich++) - eta_mass[ich] = boltz * t_target / (t_freq*t_freq); tdrag_factor = 1.0 - (update->dt * t_freq * drag / nc_tchain); } diff --git a/src/fix_nh.h b/src/fix_nh.h index 79d18a77ef..a7a3dd212f 100644 --- a/src/fix_nh.h +++ b/src/fix_nh.h @@ -104,6 +104,8 @@ class FixNH : public Fix { double mtk_term1,mtk_term2; // Martyna-Tobias-Klein corrections + int eta_mass_flag; // 1 if eta_mass updated, 0 if not. + int scaleyz; // 1 if yz scaled with lz int scalexz; // 1 if xz scaled with lz int scalexy; // 1 if xy scaled with ly From a34506c42008eed195e3529639dae74542e3557f Mon Sep 17 00:00:00 2001 From: athomps Date: Tue, 13 Sep 2011 20:34:02 +0000 Subject: [PATCH 109/246] Added flag to make only fix_nphug use constant eta_mass git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6944 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 4 +++- src/fix_nh.cpp | 48 +++++++++++++++++++++++++++++++---------- src/fix_nh.h | 2 ++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 16ba8ffed8..e915509474 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -36,9 +36,11 @@ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { - // Prevent eta_mass from being updated every timestep + // Prevent masses from being updated every timestep eta_mass_flag = 0; + omega_mass_flag = 0; + etap_mass_flag = 0; // extend vector of base-class computes diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 16005c199a..6f59d53fe9 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -73,6 +73,8 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 0; nreset_h0 = 0; eta_mass_flag = 1; + omega_mass_flag = 0; + etap_mass_flag = 0; // turn on tilt factor scaling, whenever applicable @@ -732,11 +734,6 @@ void FixNH::initial_integrate(int vflag) if (tstat_flag) { compute_temp_target(); - if (eta_mass_flag) { - eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); - for (int ich = 1; ich < mtchain; ich++) - eta_mass[ich] = boltz * t_target / (t_freq*t_freq); - } nhc_temp_integrate(); } @@ -833,11 +830,6 @@ void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop) if (tstat_flag) { compute_temp_target(); - if (eta_mass_flag) { - eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); - for (int ich = 1; ich < mtchain; ich++) - eta_mass[ich] = boltz * t_target / (t_freq*t_freq); - } nhc_temp_integrate(); } @@ -1597,8 +1589,16 @@ void FixNH::nhc_temp_integrate() { int ich; double expfac; - double kecurrent = tdof * boltz * t_current; + + // Update masses, to preserve initial freq, if flag set + + if (eta_mass_flag) { + eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); + for (int ich = 1; ich < mtchain; ich++) + eta_mass[ich] = boltz * t_target / (t_freq*t_freq); + } + eta_dotdot[0] = (kecurrent - ke_target)/eta_mass[0]; double ncfac = 1.0/nc_tchain; @@ -1658,6 +1658,32 @@ void FixNH::nhc_press_integrate() double kt = boltz * t_target; double lkt_press = kt; + // Update masses, to preserve initial freq, if flag set + + if (omega_mass_flag) { + double nkt = atom->natoms * kt; + for (int i = 0; i < 3; i++) + if (p_flag[i]) + omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); + + if (pstyle == TRICLINIC) { + for (int i = 3; i < 6; i++) + if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); + } + } + + if (etap_mass_flag) { + if (mpchain) { + etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max); + for (int ich = 1; ich < mpchain; ich++) + etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max); + for (int ich = 1; ich < mpchain; ich++) + etap_dotdot[ich] = + (etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] - + boltz * t_target) / etap_mass[ich]; + } + } + kecurrent = 0.0; for (i = 0; i < 3; i++) if (p_flag[i]) kecurrent += omega_mass[i]*omega_dot[i]*omega_dot[i]; diff --git a/src/fix_nh.h b/src/fix_nh.h index a7a3dd212f..15c4cea24b 100644 --- a/src/fix_nh.h +++ b/src/fix_nh.h @@ -105,6 +105,8 @@ class FixNH : public Fix { double mtk_term1,mtk_term2; // Martyna-Tobias-Klein corrections int eta_mass_flag; // 1 if eta_mass updated, 0 if not. + int omega_mass_flag; // 1 if omega_mass updated, 0 if not. + int etap_mass_flag; // 1 if etap_mass updated, 0 if not. int scaleyz; // 1 if yz scaled with lz int scalexz; // 1 if xz scaled with lz From dfa59d7cb02d0a1b63097793468d65d24ba0afc3 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:07:53 +0000 Subject: [PATCH 110/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6945 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 4 ++-- src/SHOCK/fix_nphug.h | 3 ++- src/fix_nh.cpp | 4 ++-- src/fix_nh.h | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index e915509474..9d0df7dd94 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -402,13 +402,13 @@ int FixNPHug::pack_restart_data(double *list) calculate the number of data to be packed ------------------------------------------------------------------------- */ -int FixNPHug::size_restart() +int FixNPHug::size_restart_global() { int nsize = 3; // call the base class function - nsize += FixNH::size_restart(); + nsize += FixNH::size_restart_global(); return nsize; } diff --git a/src/SHOCK/fix_nphug.h b/src/SHOCK/fix_nphug.h index 47ef8d1b5a..f70ebf632e 100644 --- a/src/SHOCK/fix_nphug.h +++ b/src/SHOCK/fix_nphug.h @@ -32,7 +32,6 @@ class FixNPHug : public FixNH { void setup(int); int modify_param(int, char **); int pack_restart_data(double *); // pack restart data - int size_restart(); // return size void restart(char *); private: @@ -52,6 +51,8 @@ class FixNPHug : public FixNH { double v0,p0,e0,rho0; int idir; int uniaxial; + + int size_restart_global(); }; } diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 6f59d53fe9..2854893057 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -1118,7 +1118,7 @@ void FixNH::remap() void FixNH::write_restart(FILE *fp) { - int nsize = size_restart(); + int nsize = size_restart_global(); double *list; memory->create(list,nsize,"nh:list"); @@ -1138,7 +1138,7 @@ void FixNH::write_restart(FILE *fp) calculate the number of data to be packed ------------------------------------------------------------------------- */ -int FixNH::size_restart() +int FixNH::size_restart_global() { int nsize = 2; if (tstat_flag) nsize += 1 + 2*mtchain; diff --git a/src/fix_nh.h b/src/fix_nh.h index 15c4cea24b..9ed1cab142 100644 --- a/src/fix_nh.h +++ b/src/fix_nh.h @@ -34,7 +34,6 @@ class FixNH : public Fix { virtual double compute_vector(int); void write_restart(FILE *); virtual int pack_restart_data(double *); // pack restart data - virtual int size_restart(); // return size virtual void restart(char *); int modify_param(int, char **); void reset_target(double); @@ -122,6 +121,7 @@ class FixNH : public Fix { virtual void nh_v_press(); virtual void nh_v_temp(); virtual void compute_temp_target(); + virtual int size_restart_global(); void compute_sigma(); void compute_deviatoric(); From 42da26e3071c4c2bc0c8239ff2c58fbd01c110e7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:13:14 +0000 Subject: [PATCH 111/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6946 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- examples/README | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/README b/examples/README index 5915f61cb5..ffad2e66c5 100644 --- a/examples/README +++ b/examples/README @@ -34,6 +34,7 @@ ellipse: ellipsoidal particles in spherical solvent, 2d system flow: Couette and Poiseuille flow in a 2d channel friction: frictional contact of spherical asperities between 2d surfaces gpu: use of the GPU package for GPU acceleration +hugoniostat: Hugoniostat shock dynamics indent: spherical indenter into a 2d solid meam: MEAM test for SiC and shear (same as shear examples) melt: rapid melt of 3d LJ system From 0f64d1745ff20dfb174b13fc48d3ff78f95cfa0c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:14:36 +0000 Subject: [PATCH 112/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6947 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 14 +++++++------- doc/Section_commands.txt | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 31c0ea6317..b9102e9ea8 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -340,13 +340,13 @@ of each style or click on the style itself for a full description: bond/breakbond/createbond/swapbox/relaxdeformdepositdragdt/reset efieldenforce2devaporateexternalfreezegcmcgravityheat indentlangevinlineforcemomentummovemsstnebnph -nph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/aspherenve/limit -nve/noforcenve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fccplaneforce -poemspourpress/berendsenprintqeq/combreax/bondsrecenterrestrain -rigidrigid/nverigid/nvtsetforceshakespringspring/rgspring/self -srdstore/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmdttm -viscosityviscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93wall/reflect -wall/regionwall/srd +nphugnph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/asphere +nve/limitnve/noforcenve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fcc +planeforcepoemspourpress/berendsenprintqeq/combreax/bondsrecenter +restrainrigidrigid/nverigid/nvtsetforceshakespringspring/rg +spring/selfsrdstore/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmd +ttmviscosityviscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93 +wall/reflectwall/regionwall/srd

    These are fix styles contributed by users, which can be used if diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 9ff3449d51..17bbee9487 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -429,6 +429,7 @@ of each style or click on the style itself for a full description: "msst"_fix_msst.html, "neb"_fix_neb.html, "nph"_fix_nh.html, +"nphug"_fix_nphug.html, "nph/asphere"_fix_nph_asphere.html, "nph/sphere"_fix_nph_sphere.html, "npt"_fix_nh.html, From a24074928b07187959bbc11c9b97f64f5ef86f32 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:16:09 +0000 Subject: [PATCH 113/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6949 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix.html | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fix.html b/doc/fix.html index 239e0ae195..5414c3c1bc 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -193,6 +193,7 @@ list of fix styles available in LAMMPS:

  • nph - constant NPH time integration via Nose/Hoover
  • nph/asphere - NPH for aspherical particles
  • nph/sphere - NPH for spherical particles +
  • nphug - Constant-stress Hugoniostat integration
  • npt - constant NPT time integration via Nose/Hoover
  • npt/asphere - NPT for aspherical particles
  • npt/sphere - NPT for spherical particles From 45eadfb3f5522680c501af3c6b6ef3bc22ca771c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:16:46 +0000 Subject: [PATCH 114/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6950 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix.html | 2 +- doc/fix.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fix.html b/doc/fix.html index 5414c3c1bc..104f6f7eda 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -193,7 +193,7 @@ list of fix styles available in LAMMPS:
  • nph - constant NPH time integration via Nose/Hoover
  • nph/asphere - NPH for aspherical particles
  • nph/sphere - NPH for spherical particles -
  • nphug - Constant-stress Hugoniostat integration +
  • nphug - constant-stress Hugoniostat integration
  • npt - constant NPT time integration via Nose/Hoover
  • npt/asphere - NPT for aspherical particles
  • npt/sphere - NPT for spherical particles diff --git a/doc/fix.txt b/doc/fix.txt index 428b377fa1..2d70d5dded 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -188,7 +188,7 @@ list of fix styles available in LAMMPS: "nph"_fix_nh.html - constant NPH time integration via Nose/Hoover "nph/asphere"_fix_nph_asphere.html - NPH for aspherical particles "nph/sphere"_fix_nph_sphere.html - NPH for spherical particles -"nphug"_fix_nphug.html - Constant-stress Hugoniostat integration +"nphug"_fix_nphug.html - constant-stress Hugoniostat integration "npt"_fix_nh.html - constant NPT time integration via Nose/Hoover "npt/asphere"_fix_npt_asphere.html - NPT for aspherical particles "npt/sphere"_fix_npt_sphere.html - NPT for spherical particles From e8148d3d86a6d48057c574181a96a222dd99f854 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:16:55 +0000 Subject: [PATCH 115/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6951 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 702888b30b..48708bd58b 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "31 Aug 2011" +#define LAMMPS_VERSION "13 Sep 2011" From 1ef85ee3f545baa0f973cb64e27e16297184dd4f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:23:45 +0000 Subject: [PATCH 116/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6953 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/SHOCK/fix_nphug.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 9d0df7dd94..85463535c9 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -375,8 +375,7 @@ double FixNPHug::compute_vector(int n) // index not found, look in base class - FixNH::compute_vector(n); - + return FixNH::compute_vector(n); } /* ---------------------------------------------------------------------- From 847c1fe6f475093001063694285845309ba97730 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 13 Sep 2011 22:29:37 +0000 Subject: [PATCH 117/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6954 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 48708bd58b..301a2de2f1 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "13 Sep 2011" +#define LAMMPS_VERSION "14 Sep 2011" From 9baba531ca032fb9957a362b595452badcbccd10 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 15:54:09 +0000 Subject: [PATCH 118/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6958 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/Make.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Make.sh b/src/Make.sh index f2feb8f101..94c8af8b50 100644 --- a/src/Make.sh +++ b/src/Make.sh @@ -4,6 +4,8 @@ # sh Make.sh Makefile.list # function to create one style_*.h file +# must whack *.d files that depend on style_*.h file, +# else Make will not recreate them style () { list=`grep -l $1 $2*.h` @@ -20,9 +22,11 @@ style () { elif (test ! -e style_$3.h) then mv style_$3.tmp style_$3.h rm -f Obj_*/$4.d + rm -f Obj_*/lammps.d elif (test "`diff --brief style_$3.h style_$3.tmp`" != "") then mv style_$3.tmp style_$3.h rm -f Obj_*/$4.d + rm -f Obj_*/lammps.d else rm -f style_$3.tmp fi From 68006592f7ab6dd2b3ac78f49207b1d1e74d9dfe Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 18:01:42 +0000 Subject: [PATCH 119/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6959 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/run.html | 23 +++++++++++++++++++++++ doc/run.txt | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/doc/run.html b/doc/run.html index f190d487ae..ddbd74c492 100644 --- a/doc/run.html +++ b/doc/run.html @@ -159,6 +159,17 @@ print Coord = $q particular atom between runs. Note that the variable "$q" will be evaluated afresh each time the print command is executed.

    +

    IMPORTANT NOTE: You might think you could specify a command +that exits the run by jumping out of the loop, e.g. +one of these two cases: +

    +
    run		100 every 1 "jump SELF afterrun"
    +run		100 every 1 "if '$t < 1.0' then 'jump SELF afterrun'" 
    +
    +

    Unfortunately this will not currently work. The run command simply +executes each command one at a time each time it pauses, then +continues the run. +

    Note that by using the line continuation character "&", the run every command can be spread across many lines, though it is still a single command: @@ -174,6 +185,18 @@ command: run will print the full timing summary, but these operations will be skipped for intermediate runs.

    +

    IMPORTANT NOTE: You might think you could use the every option to +perform a test that exits the run by jumping or breaking out of the +loop, e.g. similar to this logic, which tests on the current +temperature: +

    +
    variable t equal temp
    +run 10000 every 100 "if '$t < 300.0' then 'jump SELF afterrun'" 
    +
    +

    Unfortunately this will not currently work. The run command simply +executes the command(s) each time it pauses, then continues the run +until completed. +

    Restrictions:

    The number of specified timesteps N must fit in a signed 32-bit diff --git a/doc/run.txt b/doc/run.txt index c3d50ed7ff..d38af3443a 100644 --- a/doc/run.txt +++ b/doc/run.txt @@ -152,6 +152,17 @@ which does 3 runs of 2000 steps and prints the x-coordinate of a particular atom between runs. Note that the variable "$q" will be evaluated afresh each time the print command is executed. +IMPORTANT NOTE: You might think you could specify a command +that exits the run by jumping out of the loop, e.g. +one of these two cases: + +run 100 every 1 "jump SELF afterrun" +run 100 every 1 "if '$t < 1.0' then 'jump SELF afterrun'" :pre + +Unfortunately this will not currently work. The run command simply +executes each command one at a time each time it pauses, then +continues the run. + Note that by using the line continuation character "&", the run every command can be spread across many lines, though it is still a single command: @@ -167,6 +178,18 @@ If the {pre} and {post} options are set to "no" when used with the run will print the full timing summary, but these operations will be skipped for intermediate runs. +IMPORTANT NOTE: You might think you could use the {every} option to +perform a test that exits the run by jumping or breaking out of the +loop, e.g. similar to this logic, which tests on the current +temperature: + +variable t equal temp +run 10000 every 100 "if '$t < 300.0' then 'jump SELF afterrun'" :pre + +Unfortunately this will not currently work. The run command simply +executes the command(s) each time it pauses, then continues the run +until completed. + [Restrictions:] The number of specified timesteps N must fit in a signed 32-bit From 1e7562efc28b3dc14d9964652846a97112724ab1 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 19:55:01 +0000 Subject: [PATCH 120/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6960 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- lib/cuda/Makefile.common | 6 +++--- lib/cuda/Makefile.cudalib | 5 +++++ lib/cuda/Makefile.lammps | 12 ++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/cuda/Makefile.common b/lib/cuda/Makefile.common index 2ad47f1e72..1952fad37b 100644 --- a/lib/cuda/Makefile.common +++ b/lib/cuda/Makefile.common @@ -14,7 +14,7 @@ SHELL = /bin/sh # System-specific settings -CUDA_INSTALL_PATH = /usr/local/cuda-3.2 +CUDA_INSTALL_PATH = /usr/local/cuda # e.g. in Gentoo # CUDA_INSTALL_PATH = /opt/cuda @@ -35,8 +35,8 @@ endif #shell echo "Compiling with precision = " ${precision} ", arch = " ${arch} ", cufft = " ${cufft} ", dbg = " ${dbg} ", prec_timer = " ${prec_timer} -CUDA_FLAGS := -DUNIX -CUDA_USRLIB_CONDITIONAL := +CUDA_FLAGS := -I${CUDA_INSTALL_PATH}/include -DUNIX +CUDA_USRLIB_CONDITIONAL := -L${CUDA_INSTALL_PATH}/lib -L${CUDA_INSTALL_PATH}/lib64 # debug setting ifeq ($(strip $(dbg)), 1) diff --git a/lib/cuda/Makefile.cudalib b/lib/cuda/Makefile.cudalib index 4d69f80873..f21e95e686 100644 --- a/lib/cuda/Makefile.cudalib +++ b/lib/cuda/Makefile.cudalib @@ -45,6 +45,11 @@ endif include Makefile.common +tmp := $(shell sed -i '2 d' Makefile.lammps) +tmp := $(shell sed -i '2 d' Makefile.lammps) +tmp := $(shell sed -i '1a CUDA_FLAGS := ${CUDA_FLAGS}' Makefile.lammps) +tmp := $(shell sed -i '2a CUDA_USRLIB_CONDITIONAL := ${CUDA_USRLIB_CONDITIONAL}' Makefile.lammps) + # verbose nvcc output during compilation ifeq ($(verbose), 1) VERBOSE := diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps index 3af9620a29..172fbc91ec 100644 --- a/lib/cuda/Makefile.lammps +++ b/lib/cuda/Makefile.lammps @@ -1,8 +1,8 @@ # Settings that the LAMMPS build will import when this package library is used + CUDA_FLAGS = -I/usr/local/cuda/include -I../../lib/cuda -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20 + CUDA_USRLIB_CONDITIONAL = -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft + + user-cuda_SYSINC = ${CUDA_FLAGS} + user-cuda_SYSLIB = -lcuda -lcudart -lrt + user-cuda_SYSPATH = $(CUDA_USRLIB_CONDITIONAL) -CUDA_INSTALL_PATH = /usr/local/cuda -CUDA_USRLIB_CONDITIONAL = - -user-cuda_SYSINC = -I$(CUDA_INSTALL_PATH)/include -user-cuda_SYSLIB = -lcuda -lcudart -lrt -user-cuda_SYSPATH = -L$(CUDA_INSTALL_PATH)/lib64 -L$(CUDA_INSTALL_PATH)/lib $(CUDA_USRLIB_CONDITIONAL) From b73d55178b1d891ac0ad6aa76ad8412de6d61164 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 19:56:58 +0000 Subject: [PATCH 121/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6961 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 301a2de2f1..d597142301 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "14 Sep 2011" +#define LAMMPS_VERSION "15 Sep 2011" From ef7e03bb4589bb09f4f24ca901f98de19cb98cba Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 20:01:27 +0000 Subject: [PATCH 122/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6963 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-REAXC/README | 66 +++++++++++++++---------- src/USER-REAXC/fix_qeq_reax.cpp | 44 ++++++++++++----- src/USER-REAXC/fix_qeq_reax.h | 10 ++++ src/USER-REAXC/fix_reax_c.cpp | 6 +++ src/USER-REAXC/fix_reax_c.h | 10 ++++ src/USER-REAXC/pair_reax_c.cpp | 17 ++++--- src/USER-REAXC/pair_reax_c.h | 10 ++++ src/USER-REAXC/reaxc_allocate.cpp | 35 ++++++++----- src/USER-REAXC/reaxc_allocate.h | 9 +++- src/USER-REAXC/reaxc_basic_comm.cpp | 9 +++- src/USER-REAXC/reaxc_basic_comm.h | 9 +++- src/USER-REAXC/reaxc_bond_orders.cpp | 9 +++- src/USER-REAXC/reaxc_bond_orders.h | 9 +++- src/USER-REAXC/reaxc_bonds.cpp | 9 +++- src/USER-REAXC/reaxc_bonds.h | 9 +++- src/USER-REAXC/reaxc_control.cpp | 9 +++- src/USER-REAXC/reaxc_control.h | 9 +++- src/USER-REAXC/reaxc_defs.h | 9 +++- src/USER-REAXC/reaxc_ffield.cpp | 9 +++- src/USER-REAXC/reaxc_ffield.h | 9 +++- src/USER-REAXC/reaxc_forces.cpp | 9 +++- src/USER-REAXC/reaxc_forces.h | 9 +++- src/USER-REAXC/reaxc_hydrogen_bonds.cpp | 9 +++- src/USER-REAXC/reaxc_hydrogen_bonds.h | 9 +++- src/USER-REAXC/reaxc_init_md.cpp | 9 +++- src/USER-REAXC/reaxc_init_md.h | 9 +++- src/USER-REAXC/reaxc_io_tools.cpp | 9 +++- src/USER-REAXC/reaxc_io_tools.h | 9 +++- src/USER-REAXC/reaxc_list.cpp | 9 +++- src/USER-REAXC/reaxc_list.h | 9 +++- src/USER-REAXC/reaxc_lookup.cpp | 9 +++- src/USER-REAXC/reaxc_lookup.h | 9 +++- src/USER-REAXC/reaxc_multi_body.cpp | 9 +++- src/USER-REAXC/reaxc_multi_body.h | 9 +++- src/USER-REAXC/reaxc_nonbonded.cpp | 57 ++++++++++++++++++--- src/USER-REAXC/reaxc_nonbonded.h | 9 +++- src/USER-REAXC/reaxc_reset_tools.cpp | 9 +++- src/USER-REAXC/reaxc_reset_tools.h | 9 +++- src/USER-REAXC/reaxc_system_props.cpp | 9 +++- src/USER-REAXC/reaxc_system_props.h | 9 +++- src/USER-REAXC/reaxc_tool_box.cpp | 9 +++- src/USER-REAXC/reaxc_tool_box.h | 9 +++- src/USER-REAXC/reaxc_torsion_angles.cpp | 9 +++- src/USER-REAXC/reaxc_torsion_angles.h | 9 +++- src/USER-REAXC/reaxc_traj.cpp | 9 +++- src/USER-REAXC/reaxc_traj.h | 9 +++- src/USER-REAXC/reaxc_types.h | 9 +++- src/USER-REAXC/reaxc_valence_angles.cpp | 9 +++- src/USER-REAXC/reaxc_valence_angles.h | 9 +++- src/USER-REAXC/reaxc_vector.cpp | 7 ++- src/USER-REAXC/reaxc_vector.h | 9 +++- 51 files changed, 480 insertions(+), 151 deletions(-) diff --git a/src/USER-REAXC/README b/src/USER-REAXC/README index 8239788048..85ee8ed518 100644 --- a/src/USER-REAXC/README +++ b/src/USER-REAXC/README @@ -1,18 +1,9 @@ -This package contains a implementation for LAMMPS of the ReaxFF force -field. ReaxFF uses distance-dependent bond-order functions to -represent the contributions of chemical bonding to the potential -energy. It was originally developed by Adri van Duin and the Goddard -group at CalTech. +The files in this directory are a user-contributed package for LAMMPS. -The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in -C, should give identical or very similar results to pair_style reax, -which is a ReaxFF implementation on top of a Fortran library, a -version of which library was originally authored by Adri van Duin. - -The reax/c version should be somewhat faster and more scalable, -particularly with respect to the charge equilibration calculation. It -should also be easier to build and use since there are no complicating -issues with Fortran memory allocation or linking to a Fortran library. +The person who created this package is Hasan Metin Aktulga, hmaktulga +at lbl.gov, while at Purdue University. Contact him directly, +or Aidan Thompson (Sandia) at athomps at sandia.gov, if you have +questions. For technical details about this implemention of ReaxFF, see this paper: @@ -21,34 +12,55 @@ Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, Parallel Computing, to appear (2011). -See the doc page for the pair_style reax/c command for details -of how to use it in LAMMPS. - -The person who created this package is Hasan Metin Aktulga (hmaktulga -at lbl.gov), while at Purdue University. Contact him directly, or -Aidan Thompson at Sandia (athomps at sandia.gov), if you have -questions. - -------------------------------------- +Note that the files with names starting with "reaxc" in this package +are from PuReMD, the Purdue ReaxFF Molecular Dynamics Program. Its +copyright info and authorship info are listed below. + +PACKAGE DESCRIPTION: + +Contains a implementation for LAMMPS of the ReaxFF force field. +ReaxFF uses distance-dependent bond-order functions to represent the +contributions of chemical bonding to the potential energy. It was +originally developed by Adri van Duin and the Goddard group at +CalTech. + +The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in +C, should give identical or very similar results to pair_style reax, +which is a ReaxFF implementation on top of a Fortran library, a +version of which was originally authored by Adri van Duin. + +The reax/c version should be somewhat faster and more scalable, +particularly with respect to the charge equilibration calculation. It +should also be easier to build and use since there are no complicating +issues due to linking to a Fortran library. + +OTHERS FILES INCLUDED: + +User examples for pair_style reax/c are in examples/reax. + Thanks to Steve Plimpton and Aidan Thompson for their input on the LAMMPS architecture and for their help in understanding and customizing some of the required LAMMPS interfaces. -Note that files in the package with names starting with "reaxc" are -from PuReMD, the Purdue ReaxFF Molecular Dynamics Program. Its -copyright info and authorship info are listed below. +-------------------------------------- The reaxc files in this directory have the following header: PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/fix_qeq_reax.cpp b/src/USER-REAXC/fix_qeq_reax.cpp index 102faab8bc..0c7784aadd 100644 --- a/src/USER-REAXC/fix_qeq_reax.cpp +++ b/src/USER-REAXC/fix_qeq_reax.cpp @@ -13,6 +13,12 @@ /* ---------------------------------------------------------------------- Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. ------------------------------------------------------------------------- */ #include "math.h" @@ -401,9 +407,6 @@ void FixQEqReax::pre_force(int vflag) if (update->ntimestep % nevery) return; if( comm->me == 0 ) t_start = MPI_Wtime(); - if (domain->xprd < swb || domain->yprd < swb || domain->zprd < swb) - error->warning("FixQEqReax cutoff greater than periodic dimension"); - n = atom->nlocal; N = atom->nlocal + atom->nghost; // grow arrays if necessary @@ -474,19 +477,20 @@ void FixQEqReax::init_matvec() void FixQEqReax::compute_H() { int inum, jnum, *ilist, *jlist, *numneigh, **firstneigh; - int i, j, ii, jj, temp, newnbr; - int *type; - double **x; + int i, j, ii, jj, temp, newnbr, flag; + int *type, *tag; + double **x, SMALL = 0.0001; double dx, dy, dz, r_sqr; type = atom->type; + tag = atom->tag; x = atom->x; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - + // fill in the H matrix m_fill = 0; r_sqr = 0; @@ -495,16 +499,30 @@ void FixQEqReax::compute_H() jlist = firstneigh[i]; jnum = numneigh[i]; H.firstnbr[i] = m_fill; - + for( jj = 0; jj < jnum; jj++ ) { j = jlist[jj]; - - dx = x[i][0] - x[j][0]; - dy = x[i][1] - x[j][1]; - dz = x[i][2] - x[j][2]; + + dx = x[j][0] - x[i][0]; + dy = x[j][1] - x[i][1]; + dz = x[j][2] - x[i][2]; r_sqr = SQR(dx) + SQR(dy) + SQR(dz); - if( r_sqr <= SQR(swb) && (j < n || atom->tag[i] <= atom->tag[j]) ) { + flag = 0; + if (r_sqr <= SQR(swb)) { + if (j < n) flag = 1; + else if (tag[i] < tag[j]) flag = 1; + else if (tag[i] == tag[j]) { + if (dz > SMALL) flag = 1; + else if (fabs(dz) < SMALL) { + if (dy > SMALL) flag = 1; + else if (fabs(dy) < SMALL && dx > SMALL) + flag = 1; + } + } + } + + if( flag ) { H.jlist[m_fill] = j; H.val[m_fill] = calculate_H( sqrt(r_sqr), shld[type[i]][type[j]] ); m_fill++; diff --git a/src/USER-REAXC/fix_qeq_reax.h b/src/USER-REAXC/fix_qeq_reax.h index ceb3814304..9bab44179b 100644 --- a/src/USER-REAXC/fix_qeq_reax.h +++ b/src/USER-REAXC/fix_qeq_reax.h @@ -11,6 +11,16 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. +------------------------------------------------------------------------- */ + #ifdef FIX_CLASS FixStyle(qeq/reax,FixQEqReax) diff --git a/src/USER-REAXC/fix_reax_c.cpp b/src/USER-REAXC/fix_reax_c.cpp index 6fb9b5c077..f979bef1e0 100644 --- a/src/USER-REAXC/fix_reax_c.cpp +++ b/src/USER-REAXC/fix_reax_c.cpp @@ -13,6 +13,12 @@ /* ---------------------------------------------------------------------- Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. ------------------------------------------------------------------------- */ #include "fix_reax_c.h" diff --git a/src/USER-REAXC/fix_reax_c.h b/src/USER-REAXC/fix_reax_c.h index 8f663f7327..c54636ef51 100644 --- a/src/USER-REAXC/fix_reax_c.h +++ b/src/USER-REAXC/fix_reax_c.h @@ -11,6 +11,16 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. +------------------------------------------------------------------------- */ + #ifdef FIX_CLASS FixStyle(REAXC,FixReaxC) diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index d13fef914b..023dc2db36 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -13,6 +13,12 @@ /* ---------------------------------------------------------------------- Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. ------------------------------------------------------------------------- */ #include "pair_reax_c.h" @@ -27,7 +33,6 @@ #include "fix.h" #include "fix_reax_c.h" #include "memory.h" -#include "domain.h" #include "error.h" #include "reaxc_types.h" @@ -379,9 +384,6 @@ void PairReaxC::compute(int eflag, int vflag) double evdwl,ecoul; double t_start, t_end; - if (domain->xprd < cutmax || domain->yprd < cutmax || domain->zprd < cutmax) - error->warning("PairReaxC cutoff greater than periodic dimension"); - // communicate num_bonds once every reneighboring // 2 num arrays stored by fix, grab ptr to them @@ -628,16 +630,17 @@ int PairReaxC::estimate_reax_lists() int PairReaxC::write_reax_lists() { - int itr_i, itr_j, itr_g, i, j, g; + int itr_i, itr_j, itr_g, i, j, g, flag; int nlocal, nghost, num_nbrs; - int *ilist, *jlist, *numneigh, **firstneigh, *marked; + int *ilist, *jlist, *numneigh, **firstneigh, *marked, *tag; double d_sqr, g_d, g_d_sqr; rvec dvec, g_dvec; - double *dist, **x; + double *dist, **x, SMALL = 0.0001; reax_list *far_nbrs; far_neighbor_data *far_list; x = atom->x; + tag = atom->tag; nlocal = atom->nlocal; nghost = atom->nghost; ilist = list->ilist; diff --git a/src/USER-REAXC/pair_reax_c.h b/src/USER-REAXC/pair_reax_c.h index 4bf53f91c1..89c38ef9ae 100644 --- a/src/USER-REAXC/pair_reax_c.h +++ b/src/USER-REAXC/pair_reax_c.h @@ -11,6 +11,16 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Hasan Metin Aktulga, Purdue University + (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) + + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. +------------------------------------------------------------------------- */ + #ifdef PAIR_CLASS PairStyle(reax/c,PairReaxC) diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index e31c86d491..5a1eb6b986 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of @@ -744,7 +749,7 @@ void ReAllocate( reax_system *system, control_params *control, { int i, j, k, p; int num_bonds, est_3body, nflag, Nflag, Hflag, mpi_flag, ret, total_send; - int renbr; + int renbr, newsize; reallocate_data *realloc; reax_list *far_nbrs; sparse_matrix *H; @@ -781,14 +786,14 @@ void ReAllocate( reax_system *system, control_params *control, if( system->n >= DANGER_ZONE * system->local_cap || (0 && system->n <= LOOSE_ZONE * system->local_cap) ) { nflag = 1; - system->local_cap = (int)(system->n * SAFE_ZONE); + system->local_cap = MAX( (int)(system->n * SAFE_ZONE), MIN_CAP ); } Nflag = 0; if( system->N >= DANGER_ZONE * system->total_cap || (0 && system->N <= LOOSE_ZONE * system->total_cap) ) { Nflag = 1; - system->total_cap = (int)(system->N * SAFE_ZONE); + system->total_cap = MAX( (int)(system->N * SAFE_ZONE), MIN_CAP ); } if( Nflag ) { @@ -831,15 +836,16 @@ void ReAllocate( reax_system *system, control_params *control, data->step, realloc->num_far, far_nbrs->num_intrs ); MPI_Abort( comm, INSUFFICIENT_MEMORY ); } + + newsize = static_cast + (MAX( realloc->num_far*SAFE_ZONE, MIN_CAP*MIN_NBRS )); #if defined(DEBUG_FOCUS) fprintf( stderr, "p%d: reallocating far_nbrs: num_fars=%d, space=%dMB\n", system->my_rank, (int)(realloc->num_far*SAFE_ZONE), - (int)(realloc->num_far*SAFE_ZONE*sizeof(far_neighbor_data)/ - (1024*1024)) ); -#endif - Reallocate_Neighbor_List( far_nbrs, system->total_cap, - (int)(realloc->num_far*SAFE_ZONE), - comm ); + (newsize*sizeof(far_neighbor_data)/(1024*1024)) ); +#endif + + Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize, comm ); realloc->num_far = 0; } } @@ -860,8 +866,11 @@ void ReAllocate( reax_system *system, control_params *control, (int)(realloc->Htop * SAFE_ZONE * sizeof(sparse_matrix_entry) / (1024*1024)) ); #endif + + newsize = static_cast + (MAX( realloc->Htop*SAFE_ZONE, MIN_CAP*MIN_NBRS )); Reallocate_Matrix( &(workspace->H), system->local_cap, - realloc->Htop*SAFE_ZONE, "H", comm ); + newsize, "H", comm ); //Deallocate_Matrix( workspace->L ); //Deallocate_Matrix( workspace->U ); workspace->L = NULL; @@ -876,7 +885,7 @@ void ReAllocate( reax_system *system, control_params *control, if( system->numH >= DANGER_ZONE * system->Hcap || (0 && system->numH <= LOOSE_ZONE * system->Hcap) ) { Hflag = 1; - system->Hcap = (int)(system->numH * SAFE_ZONE); + system->Hcap = MAX( system->numH * SAFER_ZONE, MIN_CAP ); } if( Hflag || realloc->hbonds ) { diff --git a/src/USER-REAXC/reaxc_allocate.h b/src/USER-REAXC/reaxc_allocate.h index 04e24c67ec..e3d9049c57 100644 --- a/src/USER-REAXC/reaxc_allocate.h +++ b/src/USER-REAXC/reaxc_allocate.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_basic_comm.cpp b/src/USER-REAXC/reaxc_basic_comm.cpp index 16a46a03d8..4be0157936 100644 --- a/src/USER-REAXC/reaxc_basic_comm.cpp +++ b/src/USER-REAXC/reaxc_basic_comm.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_basic_comm.h b/src/USER-REAXC/reaxc_basic_comm.h index 986f95a175..de9f7a5316 100644 --- a/src/USER-REAXC/reaxc_basic_comm.h +++ b/src/USER-REAXC/reaxc_basic_comm.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_bond_orders.cpp b/src/USER-REAXC/reaxc_bond_orders.cpp index 26c1648a77..7649181f57 100644 --- a/src/USER-REAXC/reaxc_bond_orders.cpp +++ b/src/USER-REAXC/reaxc_bond_orders.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_bond_orders.h b/src/USER-REAXC/reaxc_bond_orders.h index 0ad8e3b836..cf8b1e6f00 100644 --- a/src/USER-REAXC/reaxc_bond_orders.h +++ b/src/USER-REAXC/reaxc_bond_orders.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_bonds.cpp b/src/USER-REAXC/reaxc_bonds.cpp index 70e0b644f2..6c83d41105 100644 --- a/src/USER-REAXC/reaxc_bonds.cpp +++ b/src/USER-REAXC/reaxc_bonds.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_bonds.h b/src/USER-REAXC/reaxc_bonds.h index bf8c111775..5a911cb21a 100644 --- a/src/USER-REAXC/reaxc_bonds.h +++ b/src/USER-REAXC/reaxc_bonds.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_control.cpp b/src/USER-REAXC/reaxc_control.cpp index 7a72a1ee6f..8773f7f059 100644 --- a/src/USER-REAXC/reaxc_control.cpp +++ b/src/USER-REAXC/reaxc_control.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_control.h b/src/USER-REAXC/reaxc_control.h index 68fd33c95d..f453ed5e60 100644 --- a/src/USER-REAXC/reaxc_control.h +++ b/src/USER-REAXC/reaxc_control.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_defs.h b/src/USER-REAXC/reaxc_defs.h index 957816d38a..52fc5487e3 100644 --- a/src/USER-REAXC/reaxc_defs.h +++ b/src/USER-REAXC/reaxc_defs.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index 2d0f37123d..3dc310b841 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_ffield.h b/src/USER-REAXC/reaxc_ffield.h index 22a580f7f8..b4632b6379 100644 --- a/src/USER-REAXC/reaxc_ffield.h +++ b/src/USER-REAXC/reaxc_ffield.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index b1d5874683..82ccebd61f 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_forces.h b/src/USER-REAXC/reaxc_forces.h index 6723bc9660..fe97a7121c 100644 --- a/src/USER-REAXC/reaxc_forces.h +++ b/src/USER-REAXC/reaxc_forces.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp index 86013abcbd..14e65ba225 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.h b/src/USER-REAXC/reaxc_hydrogen_bonds.h index bb26928d62..f25b669440 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.h +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 52466eaec9..a2d828cd9c 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_init_md.h b/src/USER-REAXC/reaxc_init_md.h index c7896f6821..26990dfdec 100644 --- a/src/USER-REAXC/reaxc_init_md.h +++ b/src/USER-REAXC/reaxc_init_md.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_io_tools.cpp b/src/USER-REAXC/reaxc_io_tools.cpp index 4020a3785e..de8830678a 100644 --- a/src/USER-REAXC/reaxc_io_tools.cpp +++ b/src/USER-REAXC/reaxc_io_tools.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_io_tools.h b/src/USER-REAXC/reaxc_io_tools.h index c009f14df7..4bca170fe5 100644 --- a/src/USER-REAXC/reaxc_io_tools.h +++ b/src/USER-REAXC/reaxc_io_tools.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_list.cpp b/src/USER-REAXC/reaxc_list.cpp index 0ea3d7d875..8e77fe185e 100644 --- a/src/USER-REAXC/reaxc_list.cpp +++ b/src/USER-REAXC/reaxc_list.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_list.h b/src/USER-REAXC/reaxc_list.h index cca217dbf7..39ca1b973e 100644 --- a/src/USER-REAXC/reaxc_list.h +++ b/src/USER-REAXC/reaxc_list.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index a4b851b9d8..0c42204610 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_lookup.h b/src/USER-REAXC/reaxc_lookup.h index 28658386b4..437f26bc77 100644 --- a/src/USER-REAXC/reaxc_lookup.h +++ b/src/USER-REAXC/reaxc_lookup.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_multi_body.cpp b/src/USER-REAXC/reaxc_multi_body.cpp index 44f3b1bcf3..f53b4709c1 100644 --- a/src/USER-REAXC/reaxc_multi_body.cpp +++ b/src/USER-REAXC/reaxc_multi_body.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_multi_body.h b/src/USER-REAXC/reaxc_multi_body.h index dcd11fc7e7..ba43b31a6d 100644 --- a/src/USER-REAXC/reaxc_multi_body.h +++ b/src/USER-REAXC/reaxc_multi_body.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_nonbonded.cpp b/src/USER-REAXC/reaxc_nonbonded.cpp index ed475606fa..eabbc16d76 100644 --- a/src/USER-REAXC/reaxc_nonbonded.cpp +++ b/src/USER-REAXC/reaxc_nonbonded.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of @@ -38,13 +43,13 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, reax_list **lists, output_controls *out_control ) { int i, j, pj, natoms; - int start_i, end_i, orig_i, orig_j; + int start_i, end_i, orig_i, orig_j, flag; real p_vdW1, p_vdW1i; real powr_vdW1, powgi_vdW1; real tmp, r_ij, fn13, exp1, exp2; real Tap, dTap, dfn13, CEvd, CEclmb, de_core; real dr3gamij_1, dr3gamij_3; - real e_ele, e_vdW, e_core; + real e_ele, e_vdW, e_core, SMALL = 0.0001; rvec temp, ext_press; two_body_parameters *twbp; far_neighbor_data *nbr_pj; @@ -69,9 +74,27 @@ void vdW_Coulomb_Energy( reax_system *system, control_params *control, j = nbr_pj->nbr; orig_j = system->my_atoms[j].orig_id; +#if defined(PURE_REAX) if( nbr_pj->d <= control->nonb_cut && (j < natoms || orig_i < orig_j) ) { - r_ij = nbr_pj->d; - twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] +#elif defined(LAMMPS_REAX) + flag = 0; + if(nbr_pj->d <= control->nonb_cut) { + if (j < natoms) flag = 1; + else if (orig_i < orig_j) flag = 1; + else if (orig_i == orig_j) { + if (nbr_pj->dvec[2] > SMALL) flag = 1; + else if (fabs(nbr_pj->dvec[2]) < SMALL) { + if (nbr_pj->dvec[1] > SMALL) flag = 1; + else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) + flag = 1; + } + } + } + + if (flag) { +#endif + r_ij = nbr_pj->d; + twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [ system->my_atoms[j].type ]); /* Calculate Taper and its derivative */ @@ -212,10 +235,10 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, { int i, j, pj, r, natoms, steps, update_freq, update_energies; int type_i, type_j, tmin, tmax; - int start_i, end_i, orig_i, orig_j; + int start_i, end_i, orig_i, orig_j, flag; real r_ij, base, dif; real e_vdW, e_ele; - real CEvd, CEclmb; + real CEvd, CEclmb, SMALL = 0.0001; rvec temp, ext_press; far_neighbor_data *nbr_pj; reax_list *far_nbrs; @@ -239,7 +262,25 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, j = nbr_pj->nbr; orig_j = system->my_atoms[j].orig_id; +#if defined(PURE_REAX) if( nbr_pj->d <= control->nonb_cut && (j < natoms || orig_i < orig_j) ) { +#elif defined(LAMMPS_REAX) + flag = 0; + if(nbr_pj->d <= control->nonb_cut) { + if (j < natoms) flag = 1; + else if (orig_i < orig_j) flag = 1; + else if (orig_i == orig_j) { + if (nbr_pj->dvec[2] > SMALL) flag = 1; + else if (fabs(nbr_pj->dvec[2]) < SMALL) { + if (nbr_pj->dvec[1] > SMALL) flag = 1; + else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) + flag = 1; + } + } + } + + if (flag) { +#endif j = nbr_pj->nbr; type_j = system->my_atoms[j].type; r_ij = nbr_pj->d; diff --git a/src/USER-REAXC/reaxc_nonbonded.h b/src/USER-REAXC/reaxc_nonbonded.h index 7e418d43e1..81a53d82ec 100644 --- a/src/USER-REAXC/reaxc_nonbonded.h +++ b/src/USER-REAXC/reaxc_nonbonded.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index 7b7141f5a5..cc74118fcb 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_reset_tools.h b/src/USER-REAXC/reaxc_reset_tools.h index 988883dfe7..1662813a5c 100644 --- a/src/USER-REAXC/reaxc_reset_tools.h +++ b/src/USER-REAXC/reaxc_reset_tools.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_system_props.cpp b/src/USER-REAXC/reaxc_system_props.cpp index 9997394afa..81bee6c9d7 100644 --- a/src/USER-REAXC/reaxc_system_props.cpp +++ b/src/USER-REAXC/reaxc_system_props.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_system_props.h b/src/USER-REAXC/reaxc_system_props.h index 712a6f679f..fb1cc40e60 100644 --- a/src/USER-REAXC/reaxc_system_props.h +++ b/src/USER-REAXC/reaxc_system_props.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index 074921248c..a27b5030d4 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_tool_box.h b/src/USER-REAXC/reaxc_tool_box.h index 9a0b60247b..b6666abe4f 100644 --- a/src/USER-REAXC/reaxc_tool_box.h +++ b/src/USER-REAXC/reaxc_tool_box.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_torsion_angles.cpp b/src/USER-REAXC/reaxc_torsion_angles.cpp index f1afe3c3a6..33b1c5568f 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.cpp +++ b/src/USER-REAXC/reaxc_torsion_angles.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_torsion_angles.h b/src/USER-REAXC/reaxc_torsion_angles.h index d3c25501e6..a34ef7709e 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.h +++ b/src/USER-REAXC/reaxc_torsion_angles.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index 0aaa413156..89f178b3ad 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_traj.h b/src/USER-REAXC/reaxc_traj.h index 99e0c5223a..074e65df28 100644 --- a/src/USER-REAXC/reaxc_traj.h +++ b/src/USER-REAXC/reaxc_traj.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h index be0378de39..b288ceff3f 100644 --- a/src/USER-REAXC/reaxc_types.h +++ b/src/USER-REAXC/reaxc_types.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_valence_angles.cpp b/src/USER-REAXC/reaxc_valence_angles.cpp index 44137cde22..c2ee9408c4 100644 --- a/src/USER-REAXC/reaxc_valence_angles.cpp +++ b/src/USER-REAXC/reaxc_valence_angles.cpp @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_valence_angles.h b/src/USER-REAXC/reaxc_valence_angles.h index ac27db483d..21cb5ec451 100644 --- a/src/USER-REAXC/reaxc_valence_angles.h +++ b/src/USER-REAXC/reaxc_valence_angles.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_vector.cpp b/src/USER-REAXC/reaxc_vector.cpp index 77feddf9dd..490af6ef61 100644 --- a/src/USER-REAXC/reaxc_vector.cpp +++ b/src/USER-REAXC/reaxc_vector.cpp @@ -2,11 +2,16 @@ PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of diff --git a/src/USER-REAXC/reaxc_vector.h b/src/USER-REAXC/reaxc_vector.h index 3771406478..b3bdba4025 100644 --- a/src/USER-REAXC/reaxc_vector.h +++ b/src/USER-REAXC/reaxc_vector.h @@ -1,12 +1,17 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program - + Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu + Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu + Please cite the related publication: + H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, + "Parallel Reactive Molecular Dynamics: Numerical Methods and + Algorithmic Techniques", Parallel Computing, in press. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of From aa896067951a4f07086a6c7d9dd0e30bae88dd1b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 20:10:35 +0000 Subject: [PATCH 123/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6964 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-REAXC/README | 59 +++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/src/USER-REAXC/README b/src/USER-REAXC/README index 85ee8ed518..cdcfb17603 100644 --- a/src/USER-REAXC/README +++ b/src/USER-REAXC/README @@ -1,50 +1,43 @@ -The files in this directory are a user-contributed package for LAMMPS. +This package contains a implementation for LAMMPS of the ReaxFF force +field. ReaxFF uses distance-dependent bond-order functions to +represent the contributions of chemical bonding to the potential +energy. It was originally developed by Adri van Duin and the Goddard +group at CalTech. -The person who created this package is Hasan Metin Aktulga, hmaktulga -at lbl.gov, while at Purdue University. Contact him directly, -or Aidan Thompson (Sandia) at athomps at sandia.gov, if you have -questions. +The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in +C, should give identical or very similar results to pair_style reax, +which is a ReaxFF implementation on top of a Fortran library, a +version of which library was originally authored by Adri van Duin. + +The reax/c version should be somewhat faster and more scalable, +particularly with respect to the charge equilibration calculation. It +should also be easier to build and use since there are no complicating +issues with Fortran memory allocation or linking to a Fortran library. For technical details about this implemention of ReaxFF, see this paper: Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty, -S. A. Pandit, A. Y. Grama, Parallel Computing, to appear (2011). +S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011). + +See the doc page for the pair_style reax/c command for details +of how to use it in LAMMPS. + +The person who created this package is Hasan Metin Aktulga (hmaktulga +at lbl.gov), while at Purdue University. Contact him directly, or +Aidan Thompson at Sandia (athomps at sandia.gov), if you have +questions. -------------------------------------- -Note that the files with names starting with "reaxc" in this package -are from PuReMD, the Purdue ReaxFF Molecular Dynamics Program. Its -copyright info and authorship info are listed below. - -PACKAGE DESCRIPTION: - -Contains a implementation for LAMMPS of the ReaxFF force field. -ReaxFF uses distance-dependent bond-order functions to represent the -contributions of chemical bonding to the potential energy. It was -originally developed by Adri van Duin and the Goddard group at -CalTech. - -The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in -C, should give identical or very similar results to pair_style reax, -which is a ReaxFF implementation on top of a Fortran library, a -version of which was originally authored by Adri van Duin. - -The reax/c version should be somewhat faster and more scalable, -particularly with respect to the charge equilibration calculation. It -should also be easier to build and use since there are no complicating -issues due to linking to a Fortran library. - -OTHERS FILES INCLUDED: - -User examples for pair_style reax/c are in examples/reax. - Thanks to Steve Plimpton and Aidan Thompson for their input on the LAMMPS architecture and for their help in understanding and customizing some of the required LAMMPS interfaces. --------------------------------------- +Note that files in the package with names starting with "reaxc" are +from PuReMD, the Purdue ReaxFF Molecular Dynamics Program. Its +copyright info and authorship info are listed below. The reaxc files in this directory have the following header: From 426f9027c1e9e51150242c8f45adcf2fdb7999d8 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 20:10:47 +0000 Subject: [PATCH 124/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6965 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_packages.html | 2 +- doc/Section_packages.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Section_packages.html b/doc/Section_packages.html index 64de534faa..8c082f1096 100644 --- a/doc/Section_packages.html +++ b/doc/Section_packages.html @@ -350,7 +350,7 @@ this paper:

    Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty, -S. A. Pandit, A. Y. Grama, Parallel Computing, to appear (2011). +S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011).

    See the doc page for the pair_style reax/c command for details of how to use it in LAMMPS. diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt index 356611af93..3dfad2f11b 100644 --- a/doc/Section_packages.txt +++ b/doc/Section_packages.txt @@ -338,7 +338,7 @@ this paper: Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty, -S. A. Pandit, A. Y. Grama, Parallel Computing, to appear (2011). +S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011). See the doc page for the pair_style reax/c command for details of how to use it in LAMMPS. From 5d21784986480fac4ef8915dd0633023744885c4 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 20:12:56 +0000 Subject: [PATCH 125/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6966 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index d597142301..425b6b5f49 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "15 Sep 2011" +#define LAMMPS_VERSION "16 Sep 2011" From 1441940ae975804c6648d5908823b5af1f30cbe7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 20:59:08 +0000 Subject: [PATCH 126/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6968 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/fix.html | 2 +- doc/fix.txt | 2 +- doc/fix_ave_atom.html | 2 +- doc/fix_ave_atom.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/fix.html b/doc/fix.html index 104f6f7eda..e73695d95e 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -164,7 +164,7 @@ list of fix styles available in LAMMPS:

  • addforce - add a force to each atom
  • aveforce - add an averaged force to each atom
  • ave/atom - compute per-atom time-averaged quantities -
  • ave/histo - compute/output time-averaged histograms +
  • ave/histo - compute/output time-averaged histograms
  • ave/spatial - compute/output time-averaged per-atom quantities by layer
  • ave/time - compute/output global time-averaged quantities
  • bond/break - break bonds on the fly diff --git a/doc/fix.txt b/doc/fix.txt index 2d70d5dded..a31f5bf0b2 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -159,7 +159,7 @@ list of fix styles available in LAMMPS: "addforce"_fix_addforce.html - add a force to each atom "aveforce"_fix_aveforce.html - add an averaged force to each atom "ave/atom"_fix_ave_atom.html - compute per-atom time-averaged quantities -"ave/histo"_fix_ave_atom.html - compute/output time-averaged histograms +"ave/histo"_fix_ave_histo.html - compute/output time-averaged histograms "ave/spatial"_fix_ave_spatial.html - compute/output time-averaged per-atom quantities by layer "ave/time"_fix_ave_time.html - compute/output global time-averaged quantities "bond/break"_fix_bond_break.html - break bonds on the fly diff --git a/doc/fix_ave_atom.html b/doc/fix_ave_atom.html index ea961b1fd1..b93578e38b 100644 --- a/doc/fix_ave_atom.html +++ b/doc/fix_ave_atom.html @@ -40,7 +40,7 @@ one or more input values can be listed

    Examples:

    fix 1 all ave/atom 1 100 100 vx vy vz
    -fix 1 all ave/atom 10 20 1000 c_my_stress1 
    +fix 1 all ave/atom 10 20 1000 c_my_stress[1] 
     

    Description:

    diff --git a/doc/fix_ave_atom.txt b/doc/fix_ave_atom.txt index 67810b4b18..bbfab6a25b 100644 --- a/doc/fix_ave_atom.txt +++ b/doc/fix_ave_atom.txt @@ -30,7 +30,7 @@ value = x, y, z, vx, vy, vz, fx, fy, fz, c_ID, c_ID\[i\], f_ID, f_ID\[i\], v_nam [Examples:] fix 1 all ave/atom 1 100 100 vx vy vz -fix 1 all ave/atom 10 20 1000 c_my_stress[1] :pre +fix 1 all ave/atom 10 20 1000 c_my_stress\[1\] :pre [Description:] From a5efab930b0375c819484d8f9148b75e8942c5da Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 21:42:57 +0000 Subject: [PATCH 127/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6969 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_evaporate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fix_evaporate.cpp b/src/fix_evaporate.cpp index 49a19e7c8d..4e8c779561 100644 --- a/src/fix_evaporate.cpp +++ b/src/fix_evaporate.cpp @@ -232,7 +232,7 @@ void FixEvaporate::pre_exchange() // keep ndel,ndeltopo,ncount,nall,nbefore current after each mol deletion } else { - int me,proc,iatom,imolecule,ndelone,ndelall; + int me,proc,iatom,imolecule,ndelone; int *molecule = atom->molecule; ndeltopo[0] = ndeltopo[1] = ndeltopo[2] = ndeltopo[3] = 0; @@ -316,7 +316,7 @@ void FixEvaporate::pre_exchange() // update ndel,ncount,nall,nbefore - MPI_Allreduce(&ndelone,&ndelall,1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(&ndelone,&ndel,1,MPI_INT,MPI_SUM,world); MPI_Allreduce(&ncount,&nall,1,MPI_INT,MPI_SUM,world); MPI_Scan(&ncount,&nbefore,1,MPI_INT,MPI_SUM,world); nbefore -= ncount; From 063295ca99c0b5db207b28459355729df7ff233c Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 14 Sep 2011 21:56:18 +0000 Subject: [PATCH 128/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6970 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-ATC/Install.sh | 1 - src/USER-CUDA/Install.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/USER-ATC/Install.sh b/src/USER-ATC/Install.sh index 244435effe..738ebedd48 100755 --- a/src/USER-ATC/Install.sh +++ b/src/USER-ATC/Install.sh @@ -35,4 +35,3 @@ elif (test $1 = 0) then rm -f ../fix_atc.cpp fi - diff --git a/src/USER-CUDA/Install.sh b/src/USER-CUDA/Install.sh index 2994d3cdca..0375eb4d89 100755 --- a/src/USER-CUDA/Install.sh +++ b/src/USER-CUDA/Install.sh @@ -15,7 +15,7 @@ if (test $1 = 1) then sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(user-cuda_SYSPATH) |' ../Makefile.package fi - if (test -e ../Makefile.package.include) then + if (test -e ../Makefile.package.settings) then sed -i -e '/^include.*cuda.*$/d' ../Makefile.package.settings sed -i '4 i include ..\/..\/lib\/cuda\/Makefile.lammps' ../Makefile.package.settings fi From 0d0bde3e7c456484daf888337a24be64756f5b74 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 14:11:10 +0000 Subject: [PATCH 129/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6971 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/temper.html | 2 +- doc/temper.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/temper.html b/doc/temper.html index 790cc891eb..514db78868 100644 --- a/doc/temper.html +++ b/doc/temper.html @@ -115,7 +115,7 @@ log file listed the following for a simulation with 5 replicas:
  • then a setting of

    -
    variable w proc 2 4 0 1 3 
    +
    variable w world 2 4 0 1 3 
     

    would be used to restart the run with a tempering command like the example above with $w as the last argument. diff --git a/doc/temper.txt b/doc/temper.txt index c7cda7cbec..70f1e2f0d9 100644 --- a/doc/temper.txt +++ b/doc/temper.txt @@ -112,7 +112,7 @@ log file listed the following for a simulation with 5 replicas: then a setting of -variable w proc 2 4 0 1 3 :pre +variable w world 2 4 0 1 3 :pre would be used to restart the run with a tempering command like the example above with $w as the last argument. From b806706398660757bb997328d514ff6a4d18d37b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 14:26:58 +0000 Subject: [PATCH 130/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6972 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/restart2data.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/restart2data.cpp b/tools/restart2data.cpp index e1b81b7074..ec5dc81d22 100644 --- a/tools/restart2data.cpp +++ b/tools/restart2data.cpp @@ -335,7 +335,17 @@ int main (int narg, char **arg) int iarg = 1; while (iarg < narg) { - if (strcmp(arg[iarg],"-s") == 0) { + if (strcmp(arg[iarg],"-h") == 0) { + printf("Syntax: restart2data switch arg ... " + "restart-file data-file (input-file)\n"); + printf(" optional switch = -s"); + printf(" arg = suffix to remove from style names"); + printf(" restart-file and data-file are mandatory"); + printf(" input-file is optional"); + printf(" if specified it will contain LAMMPS input script commands"); + printf(" for mass and force field info"); + printf(" only a few force field styles support this option"); + } else if (strcmp(arg[iarg],"-s") == 0) { if (iarg+2 > narg) { printf("Syntax: restart2data switch arg ... " "restart-file data-file (input-file)\n"); From 67a9b06459fae7ccd356eedc7f2d0ab8b4d09967 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:30:28 +0000 Subject: [PATCH 131/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6974 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.txt | 1 + doc/pair_edip.html | 143 +++++++++++++++++++++++++++++++++++++++ doc/pair_edip.txt | 137 +++++++++++++++++++++++++++++++++++++ 3 files changed, 281 insertions(+) create mode 100644 doc/pair_edip.html create mode 100644 doc/pair_edip.txt diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 17bbee9487..3fb890bed9 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -678,6 +678,7 @@ package"_Section_start.html#start_3. "cg/cmm/coul/long"_pair_cmm.html, "dipole/sf"_pair_dipole.html, "eam/cd"_pair_eam.html, +"edip"_pair_edip.html, "eff/cut"_pair_eff.html, "lj/coul"_pair_lj_coul.html, "lj/sf"_pair_lj_sf.html, diff --git a/doc/pair_edip.html b/doc/pair_edip.html new file mode 100644 index 0000000000..7630059a00 --- /dev/null +++ b/doc/pair_edip.html @@ -0,0 +1,143 @@ + +

    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    pair_style edip command +

    +

    Syntax: +

    +
    pair_style edip 
    +
    +

    Examples: +

    +

    pair_style edip +pair_coeff * * Si.edip Si +

    +

    Description: +

    +

    The edip style computes a 3-body EDIP +potential for the energy E of a system of atoms as +

    +
    +
    +

    where phi2 is a two-body term and phi3 is a three-body term. The +summations in the formula are over all neighbors J and K of atom I +within a cutoff distance = a. +Both terms depend on the local environment of atom I through its +effective coordination number defined by Z, which is unity for a +cutoff distance < c and gently goes to 0 at distance = a. +

    +

    Only a single pair_coeff command is used with the edip style which +specifies a EDIP potential file with parameters for all +needed elements. These are mapped to LAMMPS atom types by specifying +N additional arguments after the filename in the pair_coeff command, +where N is the number of LAMMPS atom types: +

    +
    • filename +
    • N element names = mapping of EDIP elements to atom types +
    +

    As an example, imagine a file Si.edip has EDIP values for Si. +

    +

    EDIP files in the potentials directory of the LAMMPS +distribution have a ".edip" suffix. Lines that are not blank or +comments (starting with #) define parameters for a triplet of +elements. The parameters in a single entry correspond to the two-body +and three-body coefficients in the formula above: +

    +
    • element 1 (the center atom in a 3-body interaction) +
    • element 2 +
    • element 3 +
    • A (energy units) +
    • B (distance units) +
    • cutoffA (distance units) +
    • cutoffC (distance units) +
    • alpha +
    • beta +
    • eta +
    • gamma (distance units) +
    • lambda (energy units) +
    • mu +
    • tho +
    • sigma (distance units) +
    • Q0 +
    • u1 +
    • u2 +
    • u3 +
    • u4 +
    +

    The A, B, beta, sigma parameters are used only for two-body interactions. +The eta, gamma, lambda, mu, Q0 and all u1 to u4 parameters are used only +for three-body interactions. The alpha and cutoffC parameters are used +for the coordination environment function only. +

    +

    The EDIP potential file must contain entries for all the +elements listed in the pair_coeff command. It can also contain +entries for additional elements not being used in a particular +simulation; LAMMPS ignores those entries. +

    +

    For a single-element simulation, only a single entry is required +(e.g. SiSiSi). For a two-element simulation, the file must contain 8 +entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that +specify EDIP parameters for all permutations of the two elements +interacting in three-body configurations. Thus for 3 elements, 27 +entries would be required, etc. +

    +

    At the moment, only a single element parametrization is +implemented. However, the author is not aware of other +multi-element EDIP parametrizations. If you know any and +you are interest in that, please contact the author of +the EDIP package. +

    +
    + +

    Mixing, shift, table, tail correction, restart, rRESPA info: +

    +

    This pair style does not support the pair_modify +shift, table, and tail options. +

    +

    This pair style does not write its information to binary restart +files, since it is stored in potential files. Thus, you +need to re-specify the pair_style and pair_coeff commands in an input +script that reads a restart file. +

    +

    This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

    +
    + +

    Restrictions: +

    +

    This angle style can only be used if LAMMPS was built with the +USER-MISC package. See the Making LAMMPS +section for more info on packages. +

    +

    This pair style requires the newton setting to be "on" +for pair interactions. +

    +

    The EDIP potential files provided with LAMMPS (see the potentials directory) +are parameterized for metal units. +You can use the SW potential with any LAMMPS units, but you would need +to create your own EDIP potential file with coefficients listed in the +appropriate units if your simulation doesn't use "metal" units. +

    +

    Related commands: +

    +

    pair_coeff +

    +

    Default: none +

    +
    + + + +

    (EDIP) J. F. Justo et al., Phys. Rev. B 58, 2539 (1998). +

    + diff --git a/doc/pair_edip.txt b/doc/pair_edip.txt new file mode 100644 index 0000000000..7087a9c259 --- /dev/null +++ b/doc/pair_edip.txt @@ -0,0 +1,137 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style edip command :h3 + +[Syntax:] + +pair_style edip :pre + +[Examples:] + +pair_style edip +pair_coeff * * Si.edip Si + +[Description:] + +The {edip} style computes a 3-body "EDIP"_#EDIP +potential for the energy E of a system of atoms as + +:c,image(Eqs/pair_edip.jpg) + +where phi2 is a two-body term and phi3 is a three-body term. The +summations in the formula are over all neighbors J and K of atom I +within a cutoff distance = a. +Both terms depend on the local environment of atom I through its +effective coordination number defined by Z, which is unity for a +cutoff distance < c and gently goes to 0 at distance = a. + +Only a single pair_coeff command is used with the {edip} style which +specifies a EDIP potential file with parameters for all +needed elements. These are mapped to LAMMPS atom types by specifying +N additional arguments after the filename in the pair_coeff command, +where N is the number of LAMMPS atom types: + +filename +N element names = mapping of EDIP elements to atom types :ul + +As an example, imagine a file Si.edip has EDIP values for Si. + +EDIP files in the {potentials} directory of the LAMMPS +distribution have a ".edip" suffix. Lines that are not blank or +comments (starting with #) define parameters for a triplet of +elements. The parameters in a single entry correspond to the two-body +and three-body coefficients in the formula above: + +element 1 (the center atom in a 3-body interaction) +element 2 +element 3 +A (energy units) +B (distance units) +cutoffA (distance units) +cutoffC (distance units) +alpha +beta +eta +gamma (distance units) +lambda (energy units) +mu +tho +sigma (distance units) +Q0 +u1 +u2 +u3 +u4 :ul + +The A, B, beta, sigma parameters are used only for two-body interactions. +The eta, gamma, lambda, mu, Q0 and all u1 to u4 parameters are used only +for three-body interactions. The alpha and cutoffC parameters are used +for the coordination environment function only. + +The EDIP potential file must contain entries for all the +elements listed in the pair_coeff command. It can also contain +entries for additional elements not being used in a particular +simulation; LAMMPS ignores those entries. + +For a single-element simulation, only a single entry is required +(e.g. SiSiSi). For a two-element simulation, the file must contain 8 +entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that +specify EDIP parameters for all permutations of the two elements +interacting in three-body configurations. Thus for 3 elements, 27 +entries would be required, etc. + +At the moment, only a single element parametrization is +implemented. However, the author is not aware of other +multi-element EDIP parametrizations. If you know any and +you are interest in that, please contact the author of +the EDIP package. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html, since it is stored in potential files. Thus, you +need to re-specify the pair_style and pair_coeff commands in an input +script that reads a restart file. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This angle style can only be used if LAMMPS was built with the +USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info on packages. + +This pair style requires the "newton"_newton.html setting to be "on" +for pair interactions. + +The EDIP potential files provided with LAMMPS (see the potentials directory) +are parameterized for metal "units"_units.html. +You can use the SW potential with any LAMMPS units, but you would need +to create your own EDIP potential file with coefficients listed in the +appropriate units if your simulation doesn't use "metal" units. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none + +:line + +:link(EDIP) +[(EDIP)] J. F. Justo et al., Phys. Rev. B 58, 2539 (1998). From c34d7f6a7dff9a75619a7cc570b49839f4e721ba Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:30:45 +0000 Subject: [PATCH 132/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6975 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_edip.tex | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 doc/Eqs/pair_edip.tex diff --git a/doc/Eqs/pair_edip.tex b/doc/Eqs/pair_edip.tex new file mode 100644 index 0000000000..e8a1931006 --- /dev/null +++ b/doc/Eqs/pair_edip.tex @@ -0,0 +1,20 @@ +\documentclass[12pt]{article} + +\begin{document} + +\begin{eqnarray*} +E = \sum_{j \ne i} \phi_{2}(R_{ij}, Z_{i}) + \sum_{j \ne i} \sum_{k \ne i,k > j} \phi_{3}(R_{ij}, R_{ik}, Z_{i}) \\ +Z_i = \sum_{m \ne i} f(R_{im}) \qquad + f(r) = \begin{cases} + 1 & \quad ra + \end{cases} \\ +\phi_{2}(r, Z) = A\left[\left(\frac{B}{r}\right)^{\rho} - e^{-\beta Z^2}\right]exp{\left(\frac{\sigma}{r-a}\right)} \\ +\phi_{3}(R_{ij}, R_{ik}, Z_i) = exp{\left(\frac{\gamma}{R_{ij}-a}\right)}exp{\left(\frac{\gamma}{R_{ik}-a}\right)}h(cos\theta_{ijk},Z_i) \\ +h(l,Z) = \lambda [(1-e^{-Q(Z)(l+\tau(Z))^2}) + \eta Q(Z)(l+\tau(Z))^2 ] \\ +Q(Z) = Q_0 e^{-\mu Z} \qquad \tau(Z) = u_1 + u_2 (u_3 e^{-u_4 Z} - e^{-2u_4 Z}) +\end{eqnarray*} + +\end{document} + From d72cecf133c3485dcc712990241e156446b0da8d Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:35:26 +0000 Subject: [PATCH 133/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6976 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-MISC/Install.sh | 4 + src/USER-MISC/README | 7 +- src/USER-MISC/pair_edip.cpp | 1053 +++++++++++++++++++++++++++++++++++ src/USER-MISC/pair_edip.h | 119 ++++ 4 files changed, 1180 insertions(+), 3 deletions(-) create mode 100755 src/USER-MISC/pair_edip.cpp create mode 100755 src/USER-MISC/pair_edip.h diff --git a/src/USER-MISC/Install.sh b/src/USER-MISC/Install.sh index 68bc6d280a..d15156fdbd 100644 --- a/src/USER-MISC/Install.sh +++ b/src/USER-MISC/Install.sh @@ -14,6 +14,7 @@ if (test $1 = 1) then cp fix_smd.cpp .. cp pair_cdeam.cpp .. cp pair_dipole_sf.cpp .. + cp pair_edip.cpp .. cp pair_lj_sf.cpp .. cp angle_cosine_shift.h .. @@ -28,6 +29,7 @@ if (test $1 = 1) then cp fix_smd.h .. cp pair_cdeam.h .. cp pair_dipole_sf.h .. + cp pair_edip.h .. cp pair_lj_sf.h .. elif (test $1 = 0) then @@ -44,6 +46,7 @@ elif (test $1 = 0) then rm -f ../fix_smd.cpp rm -f ../pair_cdeam.cpp rm -f ../pair_dipole_sf.cpp + rm -f ../pair_edip.cpp rm -f ../pair_lj_sf.cpp rm -f ../angle_cosine_shift.h @@ -58,6 +61,7 @@ elif (test $1 = 0) then rm -f ../fix_smd.h rm -f ../pair_cdeam.h rm -f ../pair_dipole_sf.h + rm -f ../pair_edip.h rm -f ../pair_lj_sf.h fi diff --git a/src/USER-MISC/README b/src/USER-MISC/README index 6cc149a776..5eb9f8de3d 100644 --- a/src/USER-MISC/README +++ b/src/USER-MISC/README @@ -28,6 +28,7 @@ dihedral_style cosine/shift/exp, Carsten Svaneborg, science at zqex.dk, 8 Aug 11 fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11 fix imd, Axel Kohlmeyer, akohlmey at gmail.com, 9 Nov 2009 fix smd, Axel Kohlmeyer, akohlmey at gmail.com, 19 May 2008 -pair dipole/sf, Mario Orsi, orsimario at gmail.com, 8 Aug 11 -pair eam/cd, Alexander Stukowski, stukowski at mm.tu-darmstadt.de, -pair lj/sf, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11 +pair_style dipole/sf, Mario Orsi, orsimario at gmail.com, 8 Aug 11 +pair_style edip, Luca Ferraro, luca.ferraro at caspur.it, 15 Sep 11 +pair_style eam/cd, Alexander Stukowski, stukowski at mm.tu-darmstadt.de, 7 Nov 09 +pair_style lj/sf, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11 diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp new file mode 100755 index 0000000000..369877ab3d --- /dev/null +++ b/src/USER-MISC/pair_edip.cpp @@ -0,0 +1,1053 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Luca Ferraro (CASPUR) + email: luca.ferraro@caspur.it + + Environment Dependent Interatomic Potential + References: + 1) J. F. Justo, M. Z. Bazant, E. Kaxiras, V. V. Bulatov, S. Yip + Phys. Rev. B 58, 2539 (1998) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "float.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_edip.h" +#include "atom.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "force.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MAXLINE 1024 +#define DELTA 4 + +/* ---------------------------------------------------------------------- */ + +PairEDIP::PairEDIP(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 0; + one_coeff = 1; + + nelements = 0; + elements = NULL; + nparams = maxparam = 0; + params = NULL; + elem2param = NULL; +} + +/* ---------------------------------------------------------------------- + check if allocated, since class can be destructed when incomplete +------------------------------------------------------------------------- */ + +PairEDIP::~PairEDIP() +{ + if (elements) + for (int i = 0; i < nelements; i++) delete [] elements[i]; + delete [] elements; + memory->destroy(params); + memory->destroy(elem2param); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + delete [] map; + + deallocateGrids(); + deallocatePreLoops(); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::compute(int eflag, int vflag) +{ + int i,j,k,ii,inum,jnum; + int itype,jtype,ktype,ijparam,ikparam,ijkparam; + double xtmp,ytmp,ztmp,evdwl; + int *ilist,*jlist,*numneigh,**firstneigh; + register int preForceCoord_counter; + + double invR_ij; + double invR_ik; + double directorCos_ij_x; + double directorCos_ij_y; + double directorCos_ij_z; + double directorCos_ik_x; + double directorCos_ik_y; + double directorCos_ik_z; + double cosTeta; + + int interpolIDX; + double interpolTMP; + double interpolDeltaX; + double interpolY1; + double interpolY2; + + double invRMinusCutoffA; + double sigmaInvRMinusCutoffA; + double gammInvRMinusCutoffA; + double cosTetaDiff; + double cosTetaDiffCosTetaDiff; + double cutoffFunction_ij; + double exp2B_ij; + double exp2BDerived_ij; + double pow2B_ij; + double pow2BDerived_ij; + double exp3B_ij; + double exp3BDerived_ij; + double exp3B_ik; + double exp3BDerived_ik; + double qFunction; + double qFunctionDerived; + double tauFunction; + double tauFunctionDerived; + double expMinusBetaZeta_iZeta_i; + double qFunctionCosTetaDiffCosTetaDiff; + double expMinusQFunctionCosTetaDiffCosTetaDiff; + double zeta_i; + double zeta_iDerived; + double zeta_iDerivedInvR_ij; + + double forceModCoord_factor; + double forceModCoord; + double forceModCoord_ij; + double forceMod2B; + double forceMod3B_factor1_ij; + double forceMod3B_factor2_ij; + double forceMod3B_factor2; + double forceMod3B_factor1_ik; + double forceMod3B_factor2_ik; + double potentia3B_factor; + double potential2B_factor; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over full neighbor list of my atoms + + for (ii = 0; ii < inum; ii++) { + zeta_i = 0.0; + int numForceCoordPairs = 0; + + i = ilist[ii]; + itype = map[type[i]]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + // pre-loop to compute environment coordination f(Z) + + for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) { + j = jlist[neighbor_j]; + j &= NEIGHMASK; + + double dr_ij[3], r_ij; + + dr_ij[0] = xtmp - x[j][0]; + dr_ij[1] = ytmp - x[j][1]; + dr_ij[2] = ztmp - x[j][2]; + r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2]; + + jtype = map[type[j]]; + ijparam = elem2param[itype][jtype][jtype]; + if (r_ij > params[ijparam].cutsq) continue; + + r_ij = sqrt(r_ij); + + invR_ij = 1.0 / r_ij; + preInvR_ij[neighbor_j] = invR_ij; + + invRMinusCutoffA = 1.0 / (r_ij - cutoffA); + sigmaInvRMinusCutoffA = sigma * invRMinusCutoffA; + gammInvRMinusCutoffA = gamm * invRMinusCutoffA; + + interpolDeltaX = r_ij - GRIDSTART; + interpolTMP = (interpolDeltaX * GRIDDENSITY); + interpolIDX = (int) interpolTMP; + + interpolY1 = exp3B[interpolIDX]; + interpolY2 = exp3B[interpolIDX+1]; + exp3B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + exp3BDerived_ij = - exp3B_ij * gammInvRMinusCutoffA * invRMinusCutoffA; + + preExp3B_ij[neighbor_j] = exp3B_ij; + preExp3BDerived_ij[neighbor_j] = exp3BDerived_ij; + + interpolY1 = exp2B[interpolIDX]; + interpolY2 = exp2B[interpolIDX+1]; + exp2B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + exp2BDerived_ij = - exp2B_ij * sigmaInvRMinusCutoffA * invRMinusCutoffA; + + preExp2B_ij[neighbor_j] = exp2B_ij; + preExp2BDerived_ij[neighbor_j] = exp2BDerived_ij; + + interpolY1 = pow2B[interpolIDX]; + interpolY2 = pow2B[interpolIDX+1]; + pow2B_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + prePow2B_ij[neighbor_j] = pow2B_ij; + + // zeta and its derivative + + if (r_ij < cutoffC) zeta_i += 1.0; + else { + interpolY1 = cutoffFunction[interpolIDX]; + interpolY2 = cutoffFunction[interpolIDX+1]; + cutoffFunction_ij = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + zeta_i += cutoffFunction_ij; + + interpolY1 = cutoffFunctionDerived[interpolIDX]; + interpolY2 = cutoffFunctionDerived[interpolIDX+1]; + zeta_iDerived = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + zeta_iDerivedInvR_ij = zeta_iDerived * invR_ij; + + preForceCoord_counter=numForceCoordPairs*5; + preForceCoord[preForceCoord_counter+0]=zeta_iDerivedInvR_ij; + preForceCoord[preForceCoord_counter+1]=dr_ij[0]; + preForceCoord[preForceCoord_counter+2]=dr_ij[1]; + preForceCoord[preForceCoord_counter+3]=dr_ij[2]; + preForceCoord[preForceCoord_counter+4]=j; + numForceCoordPairs++; + } + } + + // quantities depending on zeta_i + + interpolDeltaX = zeta_i; + interpolTMP = (interpolDeltaX * GRIDDENSITY); + interpolIDX = (int) interpolTMP; + + interpolY1 = expMinusBetaZeta_iZeta_iGrid[interpolIDX]; + interpolY2 = expMinusBetaZeta_iZeta_iGrid[interpolIDX+1]; + expMinusBetaZeta_iZeta_i = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = qFunctionGrid[interpolIDX]; + interpolY2 = qFunctionGrid[interpolIDX+1]; + qFunction = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = tauFunctionGrid[interpolIDX]; + interpolY2 = tauFunctionGrid[interpolIDX+1]; + tauFunction = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + interpolY1 = tauFunctionDerivedGrid[interpolIDX]; + interpolY2 = tauFunctionDerivedGrid[interpolIDX+1]; + tauFunctionDerived = interpolY1 + (interpolY2 - interpolY1) * + (interpolTMP-interpolIDX); + + qFunctionDerived = -mu * qFunction; + + forceModCoord_factor = 2.0 * beta * zeta_i * expMinusBetaZeta_iZeta_i; + + forceModCoord = 0.0; + + // two-body interactions, skip half of them + + for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) { + double dr_ij[3], r_ij, f_ij[3]; + + j = jlist[neighbor_j]; + j &= NEIGHMASK; + + dr_ij[0] = x[j][0] - xtmp; + dr_ij[1] = x[j][1] - ytmp; + dr_ij[2] = x[j][2] - ztmp; + r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2]; + + jtype = map[type[j]]; + ijparam = elem2param[itype][jtype][jtype]; + if (r_ij > params[ijparam].cutsq) continue; + + r_ij = sqrt(r_ij); + + invR_ij = preInvR_ij[neighbor_j]; + pow2B_ij = prePow2B_ij[neighbor_j]; + + potential2B_factor = pow2B_ij - expMinusBetaZeta_iZeta_i; + + exp2B_ij = preExp2B_ij[neighbor_j]; + + pow2BDerived_ij = - rho * invR_ij * pow2B_ij; + + forceModCoord += (forceModCoord_factor*exp2B_ij); + + exp2BDerived_ij = preExp2BDerived_ij[neighbor_j]; + forceMod2B = exp2BDerived_ij * potential2B_factor + + exp2B_ij * pow2BDerived_ij; + + directorCos_ij_x = invR_ij * dr_ij[0]; + directorCos_ij_y = invR_ij * dr_ij[1]; + directorCos_ij_z = invR_ij * dr_ij[2]; + + exp3B_ij = preExp3B_ij[neighbor_j]; + exp3BDerived_ij = preExp3BDerived_ij[neighbor_j]; + + f_ij[0] = forceMod2B * directorCos_ij_x; + f_ij[1] = forceMod2B * directorCos_ij_y; + f_ij[2] = forceMod2B * directorCos_ij_z; + + f[j][0] -= f_ij[0]; + f[j][1] -= f_ij[1]; + f[j][2] -= f_ij[2]; + + f[i][0] += f_ij[0]; + f[i][1] += f_ij[1]; + f[i][2] += f_ij[2]; + + // potential energy + + evdwl = (exp2B_ij * potential2B_factor); + + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, + -forceMod2B*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2]); + + // three-body Forces + + for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) { + double dr_ik[3], r_ik, f_ik[3]; + + k = jlist[neighbor_k]; + k &= NEIGHMASK; + ktype = map[type[k]]; + ikparam = elem2param[itype][ktype][ktype]; + ijkparam = elem2param[itype][jtype][ktype]; + + dr_ik[0] = x[k][0] - xtmp; + dr_ik[1] = x[k][1] - ytmp; + dr_ik[2] = x[k][2] - ztmp; + r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2]; + + if (r_ik > params[ikparam].cutsq) continue; + + r_ik = sqrt(r_ik); + + invR_ik = preInvR_ij[neighbor_k]; + + directorCos_ik_x = invR_ik * dr_ik[0]; + directorCos_ik_y = invR_ik * dr_ik[1]; + directorCos_ik_z = invR_ik * dr_ik[2]; + + cosTeta = directorCos_ij_x * directorCos_ik_x + + directorCos_ij_y * directorCos_ik_y + + directorCos_ij_z * directorCos_ik_z; + + cosTetaDiff = cosTeta + tauFunction; + cosTetaDiffCosTetaDiff = cosTetaDiff * cosTetaDiff; + qFunctionCosTetaDiffCosTetaDiff = cosTetaDiffCosTetaDiff * qFunction; + expMinusQFunctionCosTetaDiffCosTetaDiff = + exp(-qFunctionCosTetaDiffCosTetaDiff); + + potentia3B_factor = lambda * + ((1.0 - expMinusQFunctionCosTetaDiffCosTetaDiff) + + eta * qFunctionCosTetaDiffCosTetaDiff); + + exp3B_ik = preExp3B_ij[neighbor_k]; + exp3BDerived_ik = preExp3BDerived_ij[neighbor_k]; + + forceMod3B_factor1_ij = - exp3BDerived_ij * exp3B_ik * + potentia3B_factor; + forceMod3B_factor2 = 2.0 * lambda * exp3B_ij * exp3B_ik * + qFunction * cosTetaDiff * + (eta + expMinusQFunctionCosTetaDiffCosTetaDiff); + forceMod3B_factor2_ij = forceMod3B_factor2 * invR_ij; + + f_ij[0] = forceMod3B_factor1_ij * directorCos_ij_x + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_x - directorCos_ik_x); + f_ij[1] = forceMod3B_factor1_ij * directorCos_ij_y + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_y - directorCos_ik_y); + f_ij[2] = forceMod3B_factor1_ij * directorCos_ij_z + + forceMod3B_factor2_ij * + (cosTeta * directorCos_ij_z - directorCos_ik_z); + + forceMod3B_factor1_ik = - exp3BDerived_ik * exp3B_ij * + potentia3B_factor; + forceMod3B_factor2_ik = forceMod3B_factor2 * invR_ik; + + f_ik[0] = forceMod3B_factor1_ik * directorCos_ik_x + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_x - directorCos_ij_x); + f_ik[1] = forceMod3B_factor1_ik * directorCos_ik_y + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_y - directorCos_ij_y); + f_ik[2] = forceMod3B_factor1_ik * directorCos_ik_z + + forceMod3B_factor2_ik * + (cosTeta * directorCos_ik_z - directorCos_ij_z); + + forceModCoord += (forceMod3B_factor2 * + (tauFunctionDerived - 0.5 * mu * cosTetaDiff)); + + f[j][0] += f_ij[0]; + f[j][1] += f_ij[1]; + f[j][2] += f_ij[2]; + + f[k][0] += f_ik[0]; + f[k][1] += f_ik[1]; + f[k][2] += f_ik[2]; + + f[i][0] -= f_ij[0] + f_ik[0]; + f[i][1] -= f_ij[1] + f_ik[1]; + f[i][2] -= f_ij[2] + f_ik[2]; + + // potential energy + + evdwl = (exp3B_ij * exp3B_ik * potentia3B_factor); + + if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik); + } + } + + // forces due to environment coordination f(Z) + + for (int idx = 0; idx < numForceCoordPairs; idx++) { + double dr_ij[3], f_ij[3]; + + preForceCoord_counter = idx * 5; + zeta_iDerivedInvR_ij=preForceCoord[preForceCoord_counter+0]; + dr_ij[0]=preForceCoord[preForceCoord_counter+1]; + dr_ij[1]=preForceCoord[preForceCoord_counter+2]; + dr_ij[2]=preForceCoord[preForceCoord_counter+3]; + j = static_cast (preForceCoord[preForceCoord_counter+4]); + + forceModCoord_ij = forceModCoord * zeta_iDerivedInvR_ij; + + f_ij[0] = forceModCoord_ij * dr_ij[0]; + f_ij[1] = forceModCoord_ij * dr_ij[1]; + f_ij[2] = forceModCoord_ij * dr_ij[2]; + + f[j][0] -= f_ij[0]; + f[j][1] -= f_ij[1]; + f[j][2] -= f_ij[2]; + + f[i][0] += f_ij[0]; + f[i][1] += f_ij[1]; + f[i][2] += f_ij[2]; + + // potential energy + + evdwl = 0.0; + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, + forceModCoord_ij, dr_ij[0], dr_ij[1], dr_ij[2]); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::allocateGrids(void) +{ + int numGridPointsOneCutoffFunction; + int numGridPointsNotOneCutoffFunction; + int numGridPointsCutoffFunction; + int numGridPointsR; + int numGridPointsRTotal; + int numGridPointsQFunctionGrid; + int numGridPointsExpMinusBetaZeta_iZeta_i; + int numGridPointsTauFunctionGrid; + double maxArgumentTauFunctionGrid; + double maxArgumentQFunctionGrid; + double maxArgumentExpMinusBetaZeta_iZeta_i; + double const leftLimitToZero = -DBL_MIN * 1000.0; + + // tauFunctionGrid + + maxArgumentTauFunctionGrid = leadDimInteractionList; + numGridPointsTauFunctionGrid = (int) + ((maxArgumentTauFunctionGrid) * GRIDDENSITY) + 2; + + memory->create(tauFunctionGrid,numGridPointsTauFunctionGrid, + "edip:tauFunctionGrid"); + memory->create(tauFunctionDerivedGrid,numGridPointsTauFunctionGrid, + "edip:tauFunctionDerivedGrid"); + + // expMinusBetaZeta_iZeta_iGrid + + maxArgumentExpMinusBetaZeta_iZeta_i = leadDimInteractionList; + numGridPointsExpMinusBetaZeta_iZeta_i = (int) + ((maxArgumentExpMinusBetaZeta_iZeta_i) * GRIDDENSITY) + 2; + memory->create(expMinusBetaZeta_iZeta_iGrid, + numGridPointsExpMinusBetaZeta_iZeta_i, + "edip:expMinusBetaZeta_iZeta_iGrid"); + + // qFunctionGrid + + maxArgumentQFunctionGrid = leadDimInteractionList; + numGridPointsQFunctionGrid = (int) + ((maxArgumentQFunctionGrid) * GRIDDENSITY) + 2; + memory->create(qFunctionGrid,numGridPointsQFunctionGrid,"edip:qFunctionGrid"); + + // cutoffFunction + + numGridPointsOneCutoffFunction = (int) ((cutoffC - GRIDSTART) * GRIDDENSITY); + numGridPointsNotOneCutoffFunction = (int) ((cutoffA-cutoffC) * GRIDDENSITY); + numGridPointsCutoffFunction = numGridPointsOneCutoffFunction + + numGridPointsNotOneCutoffFunction+2; + + memory->create(cutoffFunction,numGridPointsCutoffFunction, + "edip:cutoffFunction"); + memory->create(cutoffFunctionDerived,numGridPointsCutoffFunction, + "edip:cutoffFunctionDerived"); + + // pow2B + + numGridPointsR = (int) + ((cutoffA + leftLimitToZero - GRIDSTART) * GRIDDENSITY); + numGridPointsRTotal = numGridPointsR + 2; + + memory->create(pow2B,numGridPointsRTotal,"edip:pow2B"); + memory->create(exp2B,numGridPointsRTotal,"edip:exp2B"); + memory->create(exp3B,numGridPointsRTotal,"edip:exp3B"); +} + +/* ---------------------------------------------------------------------- + pre-calculated structures +------------------------------------------------------------------------- */ + +void PairEDIP::allocatePreLoops(void) +{ + memory->create(preInvR_ij,leadDimInteractionList,"edip:preInvR_ij"); + memory->create(preExp3B_ij,leadDimInteractionList,"edip:preExp3B_ij"); + memory->create(preExp3BDerived_ij,leadDimInteractionList, + "edip:preExp3BDerived_ij"); + memory->create(preExp2B_ij,leadDimInteractionList,"edip:preExp2B_ij"); + memory->create(preExp2BDerived_ij,leadDimInteractionList, + "edip:preExp2BDerived_ij"); + memory->create(prePow2B_ij,leadDimInteractionList,"edip:prePow2B_ij"); + memory->create(preForceCoord,5*leadDimInteractionList,"edip:preForceCoord"); +} + +/* ---------------------------------------------------------------------- + deallocate grids +------------------------------------------------------------------------- */ + +void PairEDIP::deallocateGrids(void) +{ + memory->destroy(cutoffFunction); + memory->destroy(cutoffFunctionDerived); + memory->destroy(pow2B); + memory->destroy(exp2B); + memory->destroy(exp3B); + memory->destroy(qFunctionGrid); + memory->destroy(expMinusBetaZeta_iZeta_iGrid); + memory->destroy(tauFunctionGrid); + memory->destroy(tauFunctionDerivedGrid); +} + +/* ---------------------------------------------------------------------- + deallocate preLoops +------------------------------------------------------------------------- */ + +void PairEDIP::deallocatePreLoops(void) +{ + memory->destroy(preInvR_ij); + memory->destroy(preExp3B_ij); + memory->destroy(preExp3BDerived_ij); + memory->destroy(preExp2B_ij); + memory->destroy(preExp2BDerived_ij); + memory->destroy(prePow2B_ij); + memory->destroy(preForceCoord); +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + map = new int[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairEDIP::settings(int narg, char **arg) +{ + if (narg != 0) error->all("Illegal pair_style command"); +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::initGrids(void) +{ + int l; + int numGridPointsOneCutoffFunction; + int numGridPointsNotOneCutoffFunction; + int numGridPointsCutoffFunction; + int numGridPointsR; + int numGridPointsRTotal; + int numGridPointsQFunctionGrid; + int numGridPointsExpMinusBetaZeta_iZeta_i; + int numGridPointsTauFunctionGrid; + double maxArgumentTauFunctionGrid; + double maxArgumentQFunctionGrid; + double maxArgumentExpMinusBetaZeta_iZeta_i; + double r; + double temp; + double temp3; + double temp4; + double deltaArgumentR; + double deltaArgumentCutoffFunction; + double deltaArgumentQFunctionGrid; + double deltaArgumentTauFunctionGrid; + double deltaArgumentExpMinusBetaZeta_iZeta_i; + double const leftLimitToZero = -DBL_MIN * 1000.0; + + // tauFunctionGrid + + maxArgumentTauFunctionGrid = leadDimInteractionList; + + numGridPointsTauFunctionGrid = (int) + ((maxArgumentTauFunctionGrid) * GRIDDENSITY) + 2; + + r = 0.0; + deltaArgumentTauFunctionGrid = 1.0 / GRIDDENSITY; + + for (l = 0; l < numGridPointsTauFunctionGrid; l++) { + tauFunctionGrid[l] = u1 + u2 * u3 * exp(-u4 * r) - + u2 * exp(-2.0 * u4 * r); + tauFunctionDerivedGrid[l] = - u2 * u3 * u4 * exp(-u4 * r) + + 2.0 * u2 * u4 * exp(-2.0 * u4 * r); + r += deltaArgumentTauFunctionGrid; + } + + // expMinusBetaZeta_iZeta_iGrid + + maxArgumentExpMinusBetaZeta_iZeta_i = leadDimInteractionList; + + numGridPointsExpMinusBetaZeta_iZeta_i = (int) + ((maxArgumentExpMinusBetaZeta_iZeta_i) * GRIDDENSITY) + 2; + + r = 0.0; + deltaArgumentExpMinusBetaZeta_iZeta_i = 1.0 / GRIDDENSITY; + + for (l = 0; l < numGridPointsExpMinusBetaZeta_iZeta_i; l++) { + expMinusBetaZeta_iZeta_iGrid[l] = exp(-beta * r * r); + r += deltaArgumentExpMinusBetaZeta_iZeta_i; + } + + // qFunctionGrid + + maxArgumentQFunctionGrid = leadDimInteractionList; + numGridPointsQFunctionGrid = + (int) ((maxArgumentQFunctionGrid) * GRIDDENSITY) + 2; + + r = 0.0; + deltaArgumentQFunctionGrid = 1.0 / GRIDDENSITY; + + for (l = 0; l < numGridPointsQFunctionGrid; l++) { + qFunctionGrid[l] = Q0 * exp(-mu * r); + r += deltaArgumentQFunctionGrid; + } + + // cutoffFunction + + numGridPointsOneCutoffFunction = + (int) ((cutoffC - GRIDSTART) * GRIDDENSITY); + numGridPointsNotOneCutoffFunction = + (int) ((cutoffA-cutoffC) * GRIDDENSITY); + numGridPointsCutoffFunction = + numGridPointsOneCutoffFunction+numGridPointsNotOneCutoffFunction+2; + + r = GRIDSTART; + deltaArgumentCutoffFunction = 1.0 / GRIDDENSITY; + + for (l = 0; l < numGridPointsOneCutoffFunction; l++) { + cutoffFunction[l] = 1.0; + cutoffFunctionDerived[l] = 0.0; + r += deltaArgumentCutoffFunction; + } + + for (l = numGridPointsOneCutoffFunction; + l < numGridPointsCutoffFunction; l++) { + temp = (cutoffA - cutoffC)/(r - cutoffC); + temp3 = temp * temp * temp; + temp4 = temp3 * temp; + cutoffFunction[l] = exp(alpha/(1.0-temp3)); + cutoffFunctionDerived[l] = (-3*alpha/(cutoffA-cutoffC)) * + (temp4/((1-temp3)*(1-temp3)))*exp(alpha/(1.0-temp3)); + r += deltaArgumentCutoffFunction; + } + + // pow2B + + numGridPointsR = (int) + ((cutoffA + leftLimitToZero - GRIDSTART) * GRIDDENSITY); + numGridPointsRTotal = numGridPointsR + 2; + + r = GRIDSTART; + deltaArgumentR = 1.0 / GRIDDENSITY; + for (l = 0; l < numGridPointsR; l++) { + pow2B[l] = pow((B/r),rho); + exp2B[l] = A * exp(sigma/(r-cutoffA)); + exp3B[l] = exp(gamm/(r-cutoffA)); + r += deltaArgumentR; + } + + pow2B[numGridPointsR] = pow((B/r),rho); + exp2B[numGridPointsR]=0; + exp3B[numGridPointsR]=0; + r += deltaArgumentR; + pow2B[numGridPointsR+1] = pow((B/r),rho); + exp2B[numGridPointsR+1]=0; + exp3B[numGridPointsR+1]=0; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairEDIP::coeff(int narg, char **arg) +{ + int i,j,n; + + if (!allocated) allocate(); + + if (narg != 3 + atom->ntypes) + error->all("Incorrect args for pair coefficients"); + + // insure I,J args are * * + + if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) + error->all("Incorrect args for pair coefficients"); + + // read args that map atom types to elements in potential file + // map[i] = which element the Ith atom type is, -1 if NULL + // nelements = # of unique elements + // elements = list of element names + + if (elements) { + for (i = 0; i < nelements; i++) delete [] elements[i]; + delete [] elements; + } + elements = new char*[atom->ntypes]; + for (i = 0; i < atom->ntypes; i++) elements[i] = NULL; + + nelements = 0; + for (i = 3; i < narg; i++) { + if (strcmp(arg[i],"NULL") == 0) { + map[i-2] = -1; + continue; + } + for (j = 0; j < nelements; j++) + if (strcmp(arg[i],elements[j]) == 0) break; + map[i-2] = j; + if (j == nelements) { + n = strlen(arg[i]) + 1; + elements[j] = new char[n]; + strcpy(elements[j],arg[i]); + nelements++; + } + } + + // read potential file and initialize potential parameters + + read_file(arg[2]); + setup(); + + // clear setflag since coeff() called once with I,J = * * + + n = atom->ntypes; + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + // set setflag i,j for type pairs where both are mapped to elements + + int count = 0; + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + if (map[i] >= 0 && map[j] >= 0) { + setflag[i][j] = 1; + count++; + } + + if (count == 0) error->all("Incorrect args for pair coefficients"); + + // allocate tables and internal structures + + allocatePreLoops(); + allocateGrids(); + initGrids(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairEDIP::init_style() +{ + if (atom->tag_enable == 0) + error->all("Pair style EDIP requires atom IDs"); + if (force->newton_pair == 0) + error->all("Pair style EDIP requires newton pair on"); + + // need a full neighbor list + + int irequest = neighbor->request(this); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairEDIP::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + + return cutmax; +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::read_file(char *file) +{ + int params_per_line = 20; + char **words = new char*[params_per_line+1]; + + memory->sfree(params); + params = NULL; + nparams = maxparam = 0; + + // open file on proc 0 + + FILE *fp; + if (comm->me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open EDIP potential file %s",file); + error->one(str); + } + } + + // read each set of params from potential file + // one set of params can span multiple lines + // store params if all 3 element tags are in element list + + int n,nwords,ielement,jelement,kelement; + char line[MAXLINE],*ptr; + int eof = 0; + + while (1) { + if (comm->me == 0) { + ptr = fgets(line,MAXLINE,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + // strip comment, skip line if blank + + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + if (nwords == 0) continue; + + // concatenate additional lines until have params_per_line words + + while (nwords < params_per_line) { + n = strlen(line); + if (comm->me == 0) { + ptr = fgets(&line[n],MAXLINE-n,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + } + + if (nwords != params_per_line) + error->all("Incorrect format in EDIP potential file"); + + // words = ptrs to all words in line + + nwords = 0; + words[nwords++] = strtok(line," \t\n\r\f"); + while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + + // ielement,jelement,kelement = 1st args + // if all 3 args are in element list, then parse this line + // else skip to next entry in file + + for (ielement = 0; ielement < nelements; ielement++) + if (strcmp(words[0],elements[ielement]) == 0) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (strcmp(words[1],elements[jelement]) == 0) break; + if (jelement == nelements) continue; + for (kelement = 0; kelement < nelements; kelement++) + if (strcmp(words[2],elements[kelement]) == 0) break; + if (kelement == nelements) continue; + + // load up parameter settings and error check their values + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), + "pair:params"); + } + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].kelement = kelement; + params[nparams].A = atof(words[3]); + params[nparams].B = atof(words[4]); + params[nparams].cutoffA = atof(words[5]); + params[nparams].cutoffC = atof(words[6]); + params[nparams].alpha = atof(words[7]); + params[nparams].beta = atof(words[8]); + params[nparams].eta = atof(words[9]); + params[nparams].gamm = atof(words[10]); + params[nparams].lambda = atof(words[11]); + params[nparams].mu = atof(words[12]); + params[nparams].rho = atof(words[13]); + params[nparams].sigma = atof(words[14]); + params[nparams].Q0 = atof(words[15]); + params[nparams].u1 = atof(words[16]); + params[nparams].u2 = atof(words[17]); + params[nparams].u3 = atof(words[18]); + params[nparams].u4 = atof(words[19]); + + if (params[nparams].A < 0.0 || params[nparams].B < 0.0 || + params[nparams].cutoffA < 0.0 || params[nparams].cutoffC < 0.0 || + params[nparams].alpha < 0.0 || params[nparams].beta < 0.0 || + params[nparams].eta < 0.0 || params[nparams].gamm < 0.0 || + params[nparams].lambda < 0.0 || params[nparams].mu < 0.0 || + params[nparams].rho < 0.0 || params[nparams].sigma < 0.0) + error->all("Illegal EDIP parameter"); + + nparams++; + } + + delete [] words; +} + +/* ---------------------------------------------------------------------- */ + +void PairEDIP::setup() +{ + int i,j,k,m,n; + double rtmp; + + // set elem2param for all triplet combinations + // must be a single exact match to lines read from file + // do not allow for ACB in place of ABC + + memory->destroy(elem2param); + memory->create(elem2param,nelements,nelements,nelements,"pair:elem2param"); + + for (i = 0; i < nelements; i++) + for (j = 0; j < nelements; j++) + for (k = 0; k < nelements; k++) { + n = -1; + for (m = 0; m < nparams; m++) { + if (i == params[m].ielement && j == params[m].jelement && + k == params[m].kelement) { + if (n >= 0) error->all("Potential file has duplicate entry"); + n = m; + } + } + if (n < 0) error->all("Potential file is missing an entry"); + elem2param[i][j][k] = n; + } + + // set cutoff square + + for (m = 0; m < nparams; m++) { + params[m].cutsq = params[m].cutoffA*params[m].cutoffA; + } + + // set cutmax to max of all params + + cutmax = 0.0; + for (m = 0; m < nparams; m++) { + rtmp = sqrt(params[m].cutsq); + if (rtmp > cutmax) cutmax = rtmp; + } + + // this should be removed for multi species parametrizations + + A = params[0].A; + B = params[0].B; + rho = params[0].rho; + cutoffA = params[0].cutoffA; + cutoffC = params[0].cutoffC; + sigma = params[0].sigma; + lambda = params[0].lambda; + gamm = params[0].gamm; + eta = params[0].eta; + Q0 = params[0].Q0; + mu = params[0].mu; + beta = params[0].beta; + alpha = params[0].alpha; + u1 = params[0].u1; + u2 = params[0].u2; + u3 = params[0].u3; + u4 = params[0].u4; +} diff --git a/src/USER-MISC/pair_edip.h b/src/USER-MISC/pair_edip.h new file mode 100755 index 0000000000..4c86b5ea3f --- /dev/null +++ b/src/USER-MISC/pair_edip.h @@ -0,0 +1,119 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(edip,PairEDIP) + +#else + +#ifndef LMP_PAIR_EDIP_H +#define LMP_PAIR_EDIP_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairEDIP : public Pair { + public: + PairEDIP(class LAMMPS *); + ~PairEDIP(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + void init_style(); + + private: + struct Param { + double A, B; + double cutoffA, cutoffC, cutsq; + double alpha, beta; + double eta, gamm, lambda, mu, rho, sigma, Q0; + double u1, u2, u3, u4; + int ielement,jelement,kelement; + }; + + double *preInvR_ij; + double *preExp3B_ij; + double *preExp3BDerived_ij; + double *preExp2B_ij; + double *preExp2BDerived_ij; + double *prePow2B_ij; + double *preForceCoord; + + // grids + + static const int GRIDDENSITY = 8000; + static const double GRIDSTART = 0.1; + + double *cutoffFunction; + double *cutoffFunctionDerived; + double *pow2B; + double *exp2B; + double *exp3B; + double *qFunctionGrid; + double *expMinusBetaZeta_iZeta_iGrid; + double *tauFunctionGrid; + double *tauFunctionDerivedGrid; + + // this should be removed for multi species parametrizations + // since these parameters should be addressed through indexes + // see also the PairEDIP::setup() + + double A; + double B; + double rho; + double cutoffA; + double cutoffC; + double sigma; + double lambda; + double gamm; + double eta; + double Q0; + double mu; + double beta; + double alpha; + double u1; + double u2; + double u3; + double u4; + + double cutmax; // max cutoff for all elements + int nelements; // # of unique elements + char **elements; // names of unique elements + int ***elem2param; // mapping from element triplets to parameters + int *map; // mapping from atom types to elements + int nparams; // # of stored parameter sets + int maxparam; // max # of parameter sets + Param *params; // parameter set for an I-J-K interaction + + // max number of interaction per atom for f(Z) environment potential + + static const int leadDimInteractionList = 64; + + void allocate(); + void allocatePreLoops(void); + void deallocatePreLoops(void); + void allocateGrids(void); + void deallocateGrids(void); + void initGrids(void); + + void read_file(char *); + void setup(); +}; + +} + +#endif +#endif From defd9d82a63e77d12ccdda94c53448148c2dddbe Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:35:41 +0000 Subject: [PATCH 134/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6977 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- potentials/Si.edip | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 potentials/Si.edip diff --git a/potentials/Si.edip b/potentials/Si.edip new file mode 100644 index 0000000000..f18ba71935 --- /dev/null +++ b/potentials/Si.edip @@ -0,0 +1,24 @@ +# EDIP parameters for various elements and mixtures +# multiple entries can be added to this file, LAMMPS reads the ones it needs +# these entries are in LAMMPS "metal" units + +# format of a single entry (one or more lines) +# +# element 1, element 2, element 3, +# A B cutoffA cutoffC alpha beta eta +# gamma lambda mu rho sigma Q0 +# u1 u2 u3 u4 +# +# units for each parameters: +# A , lambda are in eV +# B, cutoffA, cutoffC, gamma, sigma are in Angstrom +# alpha, beta, eta, mu, rho, Q0, u1-u4 are pure numbers + +# Here are the original parameters in metal units, for Silicon from: +# J. F. Justo, M. Z. Bazant, E. Kaxiras, V. V. Bulatov, S. Yip +# Phys. Rev. B 58, 2539 (1998) +# + +Si Si Si 7.9821730 1.5075463 3.1213820 2.5609104 3.1083847 0.0070975 0.2523244 + 1.1247945 1.4533108 0.6966326 1.2085196 0.5774108 312.1341346 + -0.165799 32.557 0.286198 0.66 From b2d975c1ddc1ac00aa33ed920c6c00b3e814c087 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:43:23 +0000 Subject: [PATCH 135/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6978 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 7 ++++--- doc/pair_edip.html | 7 +++++-- doc/pair_edip.txt | 7 +++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index b9102e9ea8..c5303b94d9 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -436,9 +436,10 @@ package.

    These are accelerated pair styles, which can be used if LAMMPS is diff --git a/doc/pair_edip.html b/doc/pair_edip.html index 7630059a00..4a46880dd9 100644 --- a/doc/pair_edip.html +++ b/doc/pair_edip.html @@ -22,8 +22,11 @@ pair_coeff * * Si.edip Si

    Description:

    -

    The edip style computes a 3-body EDIP -potential for the energy E of a system of atoms as +

    The edip style computes a 3-body EDIP potential which is +popular for modeling silicon materials where it can have advantages +over other models such as the Stillinger-Weber or +Tersoff potentials. In EDIP, the energy E of a +system of atoms is

    diff --git a/doc/pair_edip.txt b/doc/pair_edip.txt index 7087a9c259..af36fdd0b8 100644 --- a/doc/pair_edip.txt +++ b/doc/pair_edip.txt @@ -19,8 +19,11 @@ pair_coeff * * Si.edip Si [Description:] -The {edip} style computes a 3-body "EDIP"_#EDIP -potential for the energy E of a system of atoms as +The {edip} style computes a 3-body "EDIP"_#EDIP potential which is +popular for modeling silicon materials where it can have advantages +over other models such as the "Stillinger-Weber"_pair_sw.html or +"Tersoff"_pair_tersoff.html potentials. In EDIP, the energy E of a +system of atoms is :c,image(Eqs/pair_edip.jpg) From 0e8ea8c431f63d404589d85fe57dbb4703079cb9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:43:32 +0000 Subject: [PATCH 136/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6979 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-CUDA/Install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/USER-CUDA/Install.sh b/src/USER-CUDA/Install.sh index 0375eb4d89..3dc143471f 100755 --- a/src/USER-CUDA/Install.sh +++ b/src/USER-CUDA/Install.sh @@ -148,7 +148,6 @@ if (test $1 = 1) then cp pair_lj_gromacs_cuda.cpp .. cp pair_lj_smooth_cuda.cpp .. cp pair_morse_cuda.cpp .. - cp pppm_cuda.cpp .. cp verlet_cuda.cpp .. cp cuda.cpp .. From e76730803a3b989844dc962165d51c00df3e287b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 15 Sep 2011 15:49:37 +0000 Subject: [PATCH 137/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6981 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 425b6b5f49..719b5561f4 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "16 Sep 2011" +#define LAMMPS_VERSION "17 Sep 2011" From 4617c3cebb8995cbc145d54c6f0662865f23a2cb Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 16 Sep 2011 18:45:33 +0000 Subject: [PATCH 138/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6988 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_intro.html | 2 +- doc/Section_intro.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Section_intro.html b/doc/Section_intro.html index afc3c5d040..bced87e8c1 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -139,7 +139,7 @@ commands)

    • pairwise potentials: Lennard-Jones, Buckingham, Morse, Born-Mayer-Huggins, Yukawa, soft, class 2 (COMPASS), hydrogen bond, tabulated
    • charged pairwise potentials: Coulombic, point-dipole -
    • manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), embedded ion method (EIM), ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB +
    • manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), embedded ion method (EIM), EDIP, ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB
    • electron force field (eFF, AWPMD)
    • coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO
    • mesoscopic potentials: granular, Peridynamics, SPH diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 8422fdd8bd..95a934830a 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -136,7 +136,7 @@ commands) Yukawa, soft, class 2 (COMPASS), hydrogen bond, tabulated charged pairwise potentials: Coulombic, point-dipole manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), \ - embedded ion method (EIM), ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB + embedded ion method (EIM), EDIP, ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB electron force field (eFF, AWPMD) coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO mesoscopic potentials: granular, Peridynamics, SPH From 57b20547cd469f3c530c2ae6a8471ced95aea405 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 19 Sep 2011 14:07:29 +0000 Subject: [PATCH 139/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6990 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Eqs/pair_edip.jpg | Bin 0 -> 24897 bytes doc/Eqs/pair_edip.tex | 14 ++++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 doc/Eqs/pair_edip.jpg diff --git a/doc/Eqs/pair_edip.jpg b/doc/Eqs/pair_edip.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9e7a8d77d3e3d438d159f0994fa353951cd689e6 GIT binary patch literal 24897 zcmb@u1yEbj);}7oXp0qhr??eLvEtTZ#oeVi6f3U9B|v~uT#7phF2%j2h2R#XKmsHb zw?FsOcfb3-H}mGbb7s!WPBLe&z4lsr$#1PZEIe!gh}4u+l>lgHXaJSR8}P6UkOyF4 zU}9ooU_Cytu&|zB6X0M!UWEAgxCF$6BqYRy#KffJv=pSzsmX|mDVZp#>F5|37)U9Y zS()isY3Uj0ANm0JIA{#$WN2u_fQLZ#C~Vm-k?$40|>{8p0)fR2WV zj)snjfr0rH9|IEu4IKl3iADT`go#uTn^{)-xsVkZizg1bTpBBzu#SPXPk2UV(d=&u zk(cs{@AbSQfGr#4hN zWV5ZU;G(j`ejP0tmR4ZnGJp65*~ArMSOzI`KUi=y=Vq}58K{xq+PU%-qo2A`{FNQ| z09e6taovsIT9b%nHDb=hD5+eqW3f#6rFZo2)Ks}yjQbxG4YO;e@46t#H3gy_I#QXb za9H_fplTzxb2R_`{@=8{gZCJ*iRz#o@>hSQr#>1phEDhCr{iXf*ds+3UEaaPz!chX zjBU}KtntCIGTQICUk1;#`DC%Q!?I{2ro71;<2aghj2(YOGsTCgQ2U(T3)F|sxCuT0 z9_c)1eE|3t83t)y28R|zrYxaWbaR|P?~@hOR+@EP;sqV|-&a9r|L9=7?(D{q zo_eOH-c8y~ta?cp?`6=}cSVJq=yWNl#z9`-o(z~-;FnG-bPISl;XDaMeHl!?o&$N>3u8-`B)NIr}?Gz-n&0K z`QYcabAT;KkW;ASg+@u;#WscX`p>(k#&aBald7Yaa}Y+Y#%0_0NOJDuyW}-1uaL4| z)oFhb&}p#8c`s2r;PUMQfT#>SvN~`$?pnhLNn`7dL_U2kolD`W%KX=dPK7PvE|9Qt zwkkkz*qVluxv$@y?QUvZp~yS-P0x=><3SwmuofihmTH}3pIMQ3yuORfpo?nC7R$g{2*(`1D#mowjbBF9T z^L&uu%7QPQV@wnC8^4*)~P8)ALQ`b4XC-Wu&4o+4nN6S=cQ zUF3XAj*2aaeSR(y5EOVr7oli6TU8^h59x}ypmO(d5&%bVFu#z07y64p%08FG!;k}t! zF?!UvEE1%sz1i}*{6f^jNJ=qD-y5;n|aesZ)V1+Ni5m;@N zG%10aETHSqVh2aiEC-<7?_-uh6+(mRX(F$mOK;Du{?iFt~lDD&~;vz;uG+)Ez_2f#Wyuodo=*V5NZLaQgv3og3YJ z%Taw-HDc&@_y7=by_kOhh>i9vBae@QtA;aCrUhgpsP&Y~e48leTq^$-uO&M#QN)}O z!31j2+1Qi8dV2jQD+g#X6mDBDl-ild1;Wp94B!`5nH_;SG%g3yEqeNOjIY}x;O&5( z;jzTzC60i}80W?V9w?sZThF{<0CqLekW!CBB)J8f>uoO2QG+N2R2&4;9&m8Qe9Btw zbLkOo$oE(8aVg7{brhz-ueu)q1G@bi<>_<@Muk1?kS6=|S#=7Pxf1*aV_B-BH;muR zlDA*BLWM+E9CA=tO+tyf&5W_O$z_ICXdUzgo$h*epQ~b4(tx<@Nh0Ff4xnL6`;l$E zI$r#;U&O3jf1Ydw;QI;@gV$Q*(z`FkkK=Nl$$JMl3<(I@2_n~v(pmB#U_WyGjX$NV z+-{q9S;MKWGpU7r>D+`=n*q))gbZEH-?w;6Mqst&gw_`ZgspeWOIvitD;lW%vX&muE#{#veKBKkY$cvfdX6 zrPZGXbH5mb^Yyx;W)O1^fQjssP*xeS^QYf>j~)P1F!Q;_df=_`R@;3jk}zS>#(4MF z%VBq$F*AEtlWL^I(7=Z9RIMoNz_3%+#D>4Et|jc7A2_e1S@zw*8aFc;p3j1wlM`kj+ybinq9 zj_;|<39&@7;l@)~XH(tjBKbhW4y9U3vxr%o880-f*Kj|k+Pd~MFidhLl{YQJx-17% zp4EqI0O#qCzjw=@s(GYzMYj`EHEx}X#uFsL!Wg15%(b45W_;OkOa^bnNJmW?QNcMC3|+Wj@=18jXIjRQnSMsAF`}ZZxiS=dWllT8ua5xIdYbOe~tKU zuAyG~UW52^CBr5kMWgIh^4W&LZ0#v7KWj&SYZ6>Y)-AnkFfAPOU@(HkQk6}k6CHb( zdOgpwoyH8cX5{IdKWvBa4|!(!0EnWzvK8;lkct$lqFXM)sCod*%K%?jAiOD9yYg=m zO)M5xjMYKy`P+)TBbz&5h+;^7sU`iI@hTPmQ^~{HL%mgb(;!E`*nF_0KhFceb;jdu z=-ymc!MyZY!@v5OLqX;}yPyRe-dCCo-Q#9!8qDo&Egj$(^;a_G`-dIXDoS&~eH@Kz z9j)}(X#7rPu8+=cr7R+S;sWcAKtl$db#(fi)(^AWvlJb6mbmm`c8E5D+TWqGR2|&*L+eg zr4SIzHM};vhVKVa87X5Kg?}4mTWAh7veEWvbt`l? zdA+^@eQPedObwO$)uHGqVM+;p&6@1HqtxYVZFsjBcl{+-H%D49smFgVa(U@`cWY}F zOCkQqLPs29{52xhv44Rj(9-u=)xxrzJNZeaFpvF9spJSCF7-J|H{b$k=A3j^R(sZL zytXXwgOO_dqU2dpG0uXtBoQH!tRD%UwJ(`aUsI2@bYvn>HjE@Pt$=p=yir|`qMl#& zb~5UXGkW$uX^X=9WD?*0G#S(P2kusq4KHlYhPx`Y=gtrOnqE|85cw7=1j~+YXt@*~ z+x1N=Z|}$zP7pSGJL1k0WePA#S@^f81f$12Kgb~YXRq}w{@99Xrj+6y)5u`hJg5Bov7r&%qU<)^pin{i=V=}x#~Z>^yuIk*WoyBo zu$r6N8VN%d)(_9Gm3kz(QUJjKj0L>^j~h8OD6q0T=I;62Tb}DVQ2e=2M_MtCG!DzY zb}~1)9udstx=60%hZ(Om)NbEaT+q4$p#*NCOW&QxwvJBMrXBJP7@O&^v^N0gRaN2V zG!m@oqW==DaOX`Tm-~LHsVL50S6cgi1YnFwT;r7udAS6SP`6A=Ew(jxgsqHtyW0t* z%%bFpWVum?!L4wOXg!;Npmb!L7c_xg=xsDydr{smy$`>Fj46uV2dq>nW4( zKo-q;Q@SZD`I`zN!38W>HJSt;Y?TmyBs)|;{uz+HC1izHIM=wd4B9f~ZM3D?L7?@n zJS57V8A}?D-CM0^CY{DtWT-@m0e2g>R&l<4d+_xz=uyHvMaJ zRo$an{<0{zgM%xWZb*eDna1<3@M?B}yXnE14wW)e8_ z6v_&EUK7x5Edyijh9K&mzi+^QiMO>#3q!WskhO4l`gPvC+DN34=Onw_dR!du9%%j* zVk0ms84LId$m+fS=eWkHSNdZx_=AR6(r-)eLctV@*JYheF)E)U*W_@lpF~t*=4C$JOGBBMvTG71eVIlb z>@GFv3LF$#UL`QD9g4wx+) z{f#@~fV6ekh^%F3E%#N~WiD4c$@)Y4q)kIw`4j9I#D)cpDtXEq0&h6ozRbHHrBV?I zCiM=R{kbo$sZ`U+{C-zYGOg4QfqV4kZpC}jT1loF%Ub6AOZZR|MBG^d)ZH92ySsFt z?qn0=E#&(yK%c8Lvhk?6wo*+`MEs}USowerBI&zP{rUGly}A%ztudmLz)@L(H$U_k z)0>LwoYZuKGO|1tGiU#5kfl(l?1J}%MrU;8j26aO|kE={*nkw>TA zh%uA0dJy*Kpf5s36Elgr=|4}q|I%C~Cf#Nt01fLMXQ@z(4$fnytM-LO;&_?709JAa z>5)%2;VH(Q-pyk!u6}xA{hQUY$zkv7oB6;khC4LZd&8jz!0AR^FHyjAQ}w7_an?qv zVd` zd5w8DS>)OrOFL-onQ(+tVj3m~lA`Ia_Gu*z@zNM#PlvEKr}rst`!uR^-_|98UD0J@ zq7ASrPy1mlbv~;`N0o~t?1kl?Stm5#(gF?1kcfIE3SM-2hRPZ;L; z-6oT??dd7su4hg6ymoy_XM?&b&#qzauYx%x8|vm~s|LF|Ln<`%QWp)(C!sgqw~d|; z0GKhCPDKwRinA>XchXDMS~xMdWHL3fL?kRIEoCmdDg|aPO>bES>yjRz3*anZ)|yFc z`>}H2MRGa@J7y8Y_#=WHZj3h-q%vVEDCw%f7G-b&1-D&t*ggXzB*!SKWKTZDuwra9 zXaygN557XI$dI1u^s;R)(z-@>e=CI;aX2Qyu6I9jcF3XA*yGot?-^5L>_4yJTTi*Q zQ?XeX@v5fCOl8RAN60-}x*5X&gkD>jRQ;D6{d=-jPv2SWi42oXLb9+ou=mKdHZzQk zw7!y?^vXtKzj+&x0Z;|}@|c##O+sG1RHrF%5!!26Eg@Q&VBv(z{i(!KVGLDPfFF(s zjh4$j0Ajal++d&y!E|0vRv}kANDQw10i{1vX)>d7Gm}RU9aT<`wx~=d%>VY)xArXN zrfVUpPXHS|2Ug;{No=!*MYvp8(7_?Tk7sa9Q%^@jE`z71J8jd_+rIA3rU)BrNs`h( zha>Srw_3TxiDL_P{EbM5)Avd){^w+^?QXQ^X}1WuGs6iLgA2z*ztca1O`E_?X<9E1 z(?lJwgwg!--E)k2PInfKpFC>VV+6LGy3n+yWuC#K%Oh1`+EALTBs{jWQUk7Uf9NpK z?w1O**m^ru%_#6gnX8HD%<04q#28=SGa3YP$JI$(gDFJweCmx#qAu(an#@1nurPY}i$Xl-@8-@1ys9T-tT$-7 z3^P51kLLxS#C`MUyMw&oQ4esC^iA>KXM?>S%>10Syi4!#cuL z0rhzg0KDn`$Z5sgArxg}I?pBCb!H1ee<{$_k;;Tm0umg?kE1G`72Ba^1ecviYIyx( zVO#T^Y`t5-s^=G@9wCn2RQHYOcl*?c**f$aLRbVZ zDz&#Pna=uznO>XTarC%0w@?tD%puU~TBKGRC-2e-w`rMw<%XE5%#y9+i z58;KWRyCkd8K{pI6Nkw_uNdr>IexUXcC?B(DvaNvp!VN+Grm5^@C4)wp4T69b#Q;$ zg4@$L7*6Kv`w=^QJKfC5Lh5o@5$v$Jt1bD?b%H6DNHQ~jY3qsE9riJr%vI=&h1~zN zC$?8m2GF_1(!&0vI7M@iHZN5gff$JrJ{cyFR#;yoVu8pPZ+P0;TQVc9!Cg7zZ|zTc@L^O z8hfQEFIGWuN){Djy)L?ZPAhyW5u)o(E&ogq?z#zht_M;8Dq|n5Wyn7O-qbIPj3--! z9Eb9>H9J#$b2&e#Cg^m{NPXICbrsH0mu0?N>H5l7XB}jBB|BqcwtcL%yg24#Y36yp zc1ZA{sRHUM4Czc2eS=3a?>qefczUt~!*})fqU!up28QI7;2*AOuH@i7jeavZD?o!6 zzbV!plSS&xTF;^$LY3W!A1ah0W6AI)B%*WC zNZx6EHV|}NdkrN~N1Pvxm_Gp2(sZxjdgq!<3H~T2cPl3^K0en_!i7~b?BXo=>*$dB z4Y~{(WP`Jpq{i;ymYeVwWsr(uvUE^D%dMbvi&vN1a>)H=v5vGw&jn0Jn&|=XgM57_ z(c&>=#hbbH)la}4Ms?iHi)C(o%f2HQYd2J9s82Bok)Hd@H5@u7^L^&TX+Y+;{`!&b z3dg`2M&!7B#&?ep;l$oZNSTjAd<2yZyiC(T57Si@TX`W(H*}m4w}*TM_BqGPh}I`c z?OB{ty`?6D7aE7fx7nU(H9ZTS{zWfy;j}(miF@+<)s58hPEM=ZB)Ci96{bH52l>eD zcGh+=DuN6@YK^$(Dr3aJ zC(+@ImDW`=zv0BIk-nH83QlqoQ-%Ud?08p`dT7u=`WKMwi!^)Smd>y2)sAYRgg|Q* z9$a^>k6fKwzIZbUC(<-eUa7bUNM@0sB36IGOmCV=1-;&&d_&I8jQ^R1@9$Ob z$wMPGsP2ow4*;(Ml;%nEEw#tY85!i}5%&OwMi*@SiV3Z#?Omys7W@9ng1RU0=+Q{u zQy-}$@=L{t(gaZ9ViwtIsUdU^mo0;SNK@1gYc#6l-01% z)6g%E{Qe(?`9Fu;5=g@Puty?ztRDbZCkAezBSkx3IRuAy(`TvhRhd+MnhBzUfP`}< z)r7wdQa&$^1z?jj^>!u7rzwhF(Re6rbSD1&B6Ir6HF!9skxUuMKDd2lK{z~enKzRf z;KrI_sp$HgL?le$=M!at;h-y>P%WQ@w`S$^eG3b5u<5uKm|yUbEcF?i9}u%2-d z>@aS&NsPUF7G%Eolci-+rs?g4r_l%XbTzhj_@gtA=+=HptJ|Yzo$=56?^vl;vUmH5 z-srnGt(%h+Q)&zFd6tR5sPY)&onA-7oudC`@Yk$VPj2p;(LwR&@7>cNm~QxOGpZ#I z0O1(uisKEjkvYSNYcuWVOp7)Ae)lI{IB-7}B_jj~mo;}dod1=NO??h&{SKS6Pfmg` zmy!VV@J%@E`IOy+xK z$cvnB1xeQB877g^;DRXZo~cDYv*Lh|131Xq>Y z5o-#zD$Gi^ud6C=yQkW7jp^C3uk~)eZ8K2mIG%g1=nrig(xfE-yX3Mh(p&tUv*tBtb37y9h9byw-yeb8d9W515=2Msj8q6)pr6_? zc;Uxle1ADN^g^xtGbXRN$l}-FF^Kxm{ep1@JnLB%85_N_DgaHDhM*8#^m*;n3$+wr z@{u#{R%3he{638P`3yxxVUh0z{pROU82!wsC_NxI{( zXHCD577^hZ|KFIZlbJTQzOr`})MY~B!`liHeYHDjCd*+Y(K|&}B_N^1CDBgJMD?=x zF3U_!&rKrL(o4uY6pwAqdbFHNycB~d)rC9D5uo8NA>BJbq%a&91Y zGe#7s%z~<*;kb_Wsen?<|5!IM>u2$u&5mpv-5;Ua(!&&8n%LP^vnrE&OK*h(rn6BtTG@ z!kAVpnG|23R+gKwSv+O7*=^D;MDD>hcp`5jnV8mYnS?6BBuRb(X(|oo8lgyS9JkpV zwQ<|*Y{>~!7U83!bT`MjlVupx{UV50mK_FI?uNDBR`TnPzR4aGz zp@Et{J`AId%ba7p-`2%EWC=G<1>@u*=~7vL{cqqqng;;o?>p{5HG>>mmEr(9AC;f# z!h%1vq{d`q4Q0ZtO?p3z-h%$fY+dmVE>1WJEBZY)X@T1 zNSNf1?FME^F2vgmjWxptWXa$OOTp|;6LpQzldzg2DDZEiP|I?w|@RHlUrMAqzNA%K}nW4?w7!J}OV2CVu=_5`~WRjc1rr`9F z(tIdPOO^U`gZkLY=jmBeH=9zDQ+!akx@}9x&#YA_9se`!DhE~wz|1}(w@jT&G@=D-5ONHmRgxb9I9VFL!sv{u~~Rwucu!P5me}o!p(I5r4h( zHgRE-kwR;@sl{QX#N`P?`P^qD_TNg8f7c!>p#YOL)j-g|;vVk4a^x z4QeS@{C!$738W(nc(%fL8Sdjc#4%}Vy>`vX$G?^AxS)L5@9tq8XKhAu`c{THjBLCS z6TQ_giq{kAm#)ewv(Q%akq84`HRE-pd@xcW6Z$S>PH&V1_7XXRZ|B70nJgYtz`_J% zVaBa1`0?3N=<4rQ#{*#1RGQAV#(rqs`>Kv-U9h0X)Fnne4Xg8>{J_Kz76u;E8CEj8 zowlW?urdfF*T8M|f-&V!t1^bEzvdm!DPe2rObo#LxGu;t3N0wTzHFE=-$WLW-g7R$ zb7V?jJpai%$g{K2pp9!d>VZ$yOFE|lXa=ZY+XN3IJWcr-9EJoT83cRnW4#0S{>lWyX*vd>0n0C-REOgY z!#W|$;YKK4ZgkhJMfF|lh{fN3lslMxTzjk$m|nX^BH+OX!;LEtnM@7mn62!X4~yva8o!jxh(h0r$(&w z9R{E%UAzy9_7Z@1G07jGL=%Twb2<;Dn95Lhc1mi3RM@o}TE{C;W1>F*y6g@%~AaJiC}Rm;c zZWQD^0LrXGVU_TuStE(Vb|BL{_O`xq3`6kTbBC%T|^{^huecE0F*$83TT)S2u z^|-`Lb0=_2%<__zP$l{Um@Qr&MMFusd%dic`Cd^Hxf%LA<~c5{zsXBQ`f*GgK>g%8 z`;-kT-DoLDYJ1V&=5QW04Wn&TZN)qzHDkGCjclctoga>i{wGfT557r$%@w(#^m=-d zl0%bi1*BX@8W!N};1gb5{2nft(~-$HO}QmKmHAtvdF%5}1HXoyoWtD1z)U6MgNg!TE6F2tar)`gL!(LT)}pwF#F^8{f6Lpv?qyTc6K*w!kN)A2=?Dj zB3`XcpEh4}V%d-?_{tu@`w9S0lik_;D0uo$x)@B@K-10>)zPsG154j+l57%*bS1hf zi{$|o_oBM7AFH+6M#+xL+Z=n|9 zZ6hR*wrH%*julP6166LN?#xKCi0AK;*SjpSfzO&ZGu|VoS%%s`YJsBT{hy8af2x5Xl@jVaF$=m0 zFKg-m_cTYGk8jcBn#9f<+D8wR#twWKALz#gm{ zWqxJDMgSoVK;rqxX@E7-g1Wu7=G%Ix;yS@5mrYc0O~mZ#OravaC|iE}zjrh1HL)ZD zBG?KRAJWFvO>W75w}WyNA< z+HN;2_wRP<;BlOO9`*p}ISg~Uh#y3gN?Fa$BS~M%+czjH5H-9Wbqm$brV(qB+)KJ1^{f#u z4P2El>zcw!WJ@$N!mI9JmnPLU<=#@+!@M=^5-L0;4Vgc?UlE%v8l|RzK>=W;bM%5x zbXd}+L%TPs{0WA87GXP#3As&p_QzDtOt1|I@0LWf2 z;6M^$cP>}z>EAO19`KMuEMqt0^1dn&t_DJ^Snz|a&%}Zs7Cg6 zOxaq;i*C6hM>09v8R@CZ0&JWK^)_GfDyD>qS>XBxCp%7K>xkj0&rxPyNONP z(y`Drv_$Z3DgBh^JkfO<`wT&R-*JYVzP}#WELZe2pdi08S!8Tz0IjatCI`j=pZgqc zpYg9-XnnJ8Gg(>FL}HUU4f6{TT3NH1D?pmm`dH-N;$f}}WVGuq{rUKGdG*mlf5a1} zjVuNC{ruUyd63H{{dniVfKsZjpNA*EqY#u(9+_ZX&^>`O-n-022|VQvoqT)*d| zXvv!ISTQU!Ep-%JBSOX2hwP+ZGxfk;B}*ofzlAc57~i{+#CbqS!Y}TAllY&r1lA_2 zliH+xp*pfj)x>L377>;d;%d|xr^9h8EhZ5w*3iZ;pGGK3;ITq`j*~K zNR`k8pxp&3gw}NjdH41-Tsozh>J1I`=%1_b@UTJrj9BuwY@_KuT}i25K!3kjs3X4+ zOTU#JGWJZEj9f5`Gf3lw0~>IDq@#z6O|tRnfjj6hd@t12buzJKKn;DHb*EISclZ)2 zlfYh`5ev&glEFLxfE5Th)fNbfUw)CoxwV96pTyR;p`$Okkj?JI$(I zb)G#|0Au)CA_Y?LL)YYpC9HFBw=u<<1u~^5X;4IYyXABE0sw#E?p?GUrg3J`HmM8A zzQNumCIvOc6*{-EIVKjKJv-12*G(-JlnWvf>nVf=9*ITuD5+Ny?XxoDrvJ7xf??(Z z0Y1!#+yR#$#2s?o!*!=hy%Vl)sK?at(0QMw{h*dB&$Yx={w9 zYrBj;1+oC?jXmBTYISJ|V($PD@RzW?8{eHH+N{~is?vQFkxM_zW-VK z_QK>ZMdJ2`#z1W^LL)lE`cd6y-J;zs(nUUnlGl<3*tZ*9Gqp88cld3Rxf8OF%9K7P z(#N41(3Hl0{8;2zN!Pph%0Mr;uoA-VBzS(FBbb^YdPKbmo+%HYY?Q87m1VvC$=;8l z_p(uV%{%)v%aLTA#(}LC2q$Hk)GkXsTtK5{zF|1ZrRI8f_Kzs~pOXt2W!5e%wDNiD zavRD~+Yt0!D$OX!D4DMR%)(nTs*odA`lG_p-P=&!{OurP$LR2(O;l)$n+?dGT0d1LeY@hkf=Ys5hGyq$bDq>x?XW0}>H}U==Y;Fi;uVQ1g_4V?mdSx#8n{vy zdVsMl|Ljbd&C?jB0>(ek)DeQ1S8w%Es;mvbHDWu%IaNfj7TsfV9(?6uF3j(A`L^!$ z?EQL!yV@>UrUao)Ii_1xdgMu|&&SQ%03(gL7*QhGn|tHai3ZXguUkKEH!I*a^kG_F>#?3Fwq+}S)H~;7uU_7{?E=#Ry?99*Y0X<=)ZDlVEb8$w9_WXXd z5pRm~_O-{n-{eJM>Cp?HlVT}ZbjD$KRtSmrGE6wMGmw8_vh?&1DnQU=@8m?KzaC&# z0^lfRmJ)7XaY& zG2}y(Q3I)9&yuD7>R!H7y&c?m06fAgu-=2w(A96EF!j8?MH}93N}J|UBXd>)yzhtZ zuhm!>3Gq=+{TYd#CAXTs0%P-AjXwtMnR6wHHL+Wq@}wlJg3O8wDNIK8u9t9o8Lq=g zg4t&l(~XyHz6&AZA0dmlpAhWbdUr!@GUj>R_AIET@6xrkk9oy^mA(J?%z%5s#Ch3> z*PVB>9g^y__1F_c*ofU<*HS@bg*@5im?-7FT+FCene7DNypgM9Wn_MJ@%!l+Cj9rc zPA{F_&$Qn{4ZmK{U^$9c*x@6Y{kFCi!F5I#OMR~0}LKZN5)a}OXu_I zCKLW{uG`f9WpDlrz-3RIYahwTd~6I^nkJN+U8C`j6#f{8UT<$b`BAzQsJR0Cw;%kA z-u&x&dSs{g`NfZieJ-u&exHB!CQg3)jZqXux!vs-EbnL*RAY;NTuaWtAKraOle4!4 zqxC%&^R)B!!>X~{HpKJAIDV|HzZDHtYyU45&HT+Q8= zT|ZXjnoTBX8wHj+1ngw`;xGPVrx9FlH)a|+>$(5J6S}Va z!JxH`f=|;s+U`AUYXhUZ$pljQT!f1rldxa;0p=FQ=HGVwWNEod6u$XNOUZVFm{)lP zMSUAZj#B&5sx|zW(B5G64kP!@Ds}&hum8rnO#1Wt;fZfBch}m^<8QTG-&_L^9cJ1p z)*&9Dm(vn=FJ$ibZ~U+y0Ew{P+4Kj%QH^el*0?OD3-Q_i;n~iz7e(qnjWoZce8fiA!{90LrMh>we&cVGPsEnGzrEjB|NL>Ir6K=8+36})9LZNE$pG{ zM{>vD2O1>*O0(Xf$d)+WtUaPoKo9M5D0S@ke^suoXrPWp<0tn6;d z18L`DYY7e;SDyMC{A7XqcD`POdiBN>5MI5@UD~_!B|oG4bm6RMq#K&R9Ci?@rD%#Y zHQBgCfavPkx=c8`amuqMlSnR8+V9gb@$iFHIED{;`N#Npuk0Xn!`8`4+sh+9zM({o zA@taJ*3ZzWZR+*T8n@UnY{MKjPI0r^M{^BlHhGS|Osa(*mT8iZJpjl|oc3mHLklr~ z_m2xvbV0?3Jr{CSbBSGDMY2fNg}6oTiwsAJ1qm>NQ+hvJ^i&N*c}Ykc4cDH61>X?} ztBNRzhY_SauP05xjKC;yj4T#W?l#l2Kt!cv)IHe}0-74XTrEj)BBRpRyQ6xWR`B~3 zbm!$G4=dZtU#t_!IL1jF|R`?Oj1*6AlNr$}C1Uo^2Tn%Si%P1|m_#a}XtLl@9^EI#L-llUN# zG7VWkyvjVZZR_D@MSL7a&2p!}D?s95J_Hz5w^e;~M3OFgWm>DUojIEDnp4CWf?mB! ztiVIcv*?_fp-*>(C#0bI?sFP=-QsE$TD!cCx<{T}-vmqDgGB0+?Am~r>u{Bd;e3Lk$*bTc@$k}tT*zq@YBmFpV+4rY}j|i-|Kz8+ni!YaW$9G&RUB@~ zy6^Rs{0Dsg#JN4@CP;m^-EW3(bURNBVES}rPy-m`@X7FB#i629jK2$lm)B>Haq5r^ zAq>2jEI(d(d)fLw8z&@(+WrX* z^}fj~sNXKIaL+w9Ciorlt?Y4++M(`OWzZ7n@@WWC>^kr+xTm4ka&A)jTt7f$<2;>h zkz%HuzJ1{)iDBczj7U4hfO$E+iKEv$cgAMmCcZ+tkJMxP0T+!4;Mk;w5EYb#`KnH7 z{QJ@_RKhtuCxFKf$dkpJ_F8C+r2?NZ6pQYSPWK!9x{_~V@z-xes{flqhRp_Jcq|5?p{9X(%T7w2Rj&r$lhppXgCco(^w|xhpK{XrL^@y)| zrkc=T^X7Zs(|2uGn`q$t*Ut(THNbTi*-1YT1+66`D2k z`PJTB2T=_|n{B~s;!nf;-^wmiOzOHqT>aV)0gn9ecX~<1A1>)9uzu+9o;(y0or;LW=U~yo}yWrZSAV;As zGQ_Q#7!(Ji6saUw@Kt35@kye6co}6_)22uI?FoWdTDxd+xB@V7Mig^V% zTEQCaXro}gnj=Ps8 zuXUPw$?V2Ch#WoNzxx0+0D++f9_`Alt-z0}JNopxHFketW-`)!@84g}#gNbM9t5%Q z7qNOO>7Ywty;w&5aco4K(g8!v=0v?lUN5%qPU6?pp~Vs#!|eVVvq1}t1;1qn9_tV- zWBf!m7sLGgoxfTuNB(7Lh1@|mw-RPWw+WA2sQ|;u7p3UZa~U(RtQW}7gf3&k%O=)G z?)-)+Y3E2~Ow1%#+_P;izozQ$Bxj3+5q54g=hzXoO&)~K(&`aaxg{}rrI(6>^pi0O z>7e=7Yx99G6dwDedEJ_7Y2rxE#H6BZ88UmHRY@^R=1-^m2%PjWvF}v%ObSl_I-WmyMjy4H@5@q%SEtoNnq z+rXg5+xH(%@nZ|uPP;UBSlFgVdk{$J+SC0x=v7WVa7uG8UpJOSE-AG~LNumtnP87> z@76ncvv_zB$sZ@Q|3&qPeaisBJ2~l#8ePlEvR~v_{sRD@O=R4%RH%SaS-OPi2kPM7=_uROeKTTQMZTgB%wezV(Nf%N@*Xq*{z} zfY$57#k6V;{9p}w3-e(7z-G7cDxt3qSm~WzoxLL?l2EWrSew25-8Mtl6%Mw=SrZ_* z&zA<}e9AE_K*gR}-hEOA6`~)h*-7#UH6{%rTiP*gEFtb5rN){+(YGBg{RqUo`*yNm`3^ zJaKTE&-%-_6c(xICDlLX3z~-}lN4ZZnHkQ)Qd1*l@HM0(f~N{X7Mnc5k~XHwQ6Ct} zoWsUl*T_Do&7WSTrFwyyM!>+)nJ+A8E`z2hP&JoDm<~1GFhOCpl534dp%|HZ3$k-H zJwE5;fsAcR)5#qC1=h#^21p$s{I)-8h9?#>YGP)1uhZ&dG%cRk{oRY8wp1%e;NnzT z4p%+}?zEC(%v^e`F*si8KA}Qr#_#C=)!s~ek83p7i3foq2Q@622_}vBM-@V}1|IX-fCmnp4;1wtFjBOQd zmMJ^1#HNIP;d2vWz~GTh^Eda0)~ly%NzWLB4}ST5Fshbx;X*9j51Ul)D!=y&e8$SR zS4)2M@Z}C4gs#if6DOY7@e@2inSgnYl5JMib83d3zwpuC()_>MZYo5wcPzx&p-Ig- zFTH(K!yfOhrst^-hj8Tj8OXwakW&vg;!HpFS!lw>>?zOrj7Mg7*SH{jiSO-Yv{R0& z>ET);EveiTPq004eJUKzYjx>F(+_taWv2mZkuT5dB=%p8lsp_Lwq+IAdDSOs8P^zk zr-Ms5nAb$iz;Jx0GM?-ki7Cr7gE#-)xOg}*VadUl(@fs%Y)fDqJ2@};0d*BnZk%WA zWYLCy%Qy(@V;m2sA*CEuzm_bH6r88FiT;FuxH3N$>1`w6!kkX^@AlQvWn)cNL9Gg` zRiab~z(Yx!l+WpmN(q(GTW?fn_EirJX#e%gCFZpcnW$NaH{rZee&G!q9oMeq#}QN? z{p*2$L43Xv$-W)02O3^)4l85qy&NLNr+Ac?6*W30|HM~hKO+MpAdWRA+LzZu<@ z`ApqCDgPn2p@(v503qmu@SUiPuKEc!cL=q$pOk!&dEQpz%wFq_@VLX-St+M`f(U zwbNouj=awXX&G3QGx|+;;7*TPvzJ4D_3QU-bT<6w{P1(*V>$m22cKB5^HXO&cZgD%-{bu`KFl1;+x zPu>w6k!mACvBnZci@62Q&4e#wewaGq2jVdUbuU~6N}S01 z$W`sVt=@64f%@9M0mM|Lh@7%KyjbL9Ms*kX%bJ(<896Mbj3y=}W^lv#3gm~>t>wwx z0EG(j%9LBjo+Jls`18BQ(3Tvukz(aeKlA%f~d(T zC3B`z#mjSRHSEY@X2!+-TcBXMKK|KDAT#+{RIs#-3^e?PmS7bD4B27LX4Z}ii`?j)0PD(PYVz1{{IE046yAe}fxe^(IR{JmJ%$R|f*;^9IF zP&ZHP3Zgx<{@JeSorEA~{}jLJ^nho)&A`T@RGnEW*^^W@pGBYNg&8DPslUSfyy)FQ zyMBhuNj&fyYu%5=#+FEjm^CA6oTKlC{Khg(M2KJ!0BCJ`-gBvpY3LeaWgoU&jfkjx zzR<^z*yOj~Z=rrpee}Fol3CXAoH#REc zw|)v_wYjGR|J*!l(dD~1p^?5>bv|{VymyQ%fG?`2=wD{CiWw#?uDBv`!Y2>t_L#&y zB#qf%vW7&g9&fyNybEeHt#`ft0!A0ZPno`ai@>=F;geT6bs2~|ExYb_hu9FsZlA|~ z>k9TvInDHqqoKBq>g@otO%*jZ`pfVBx%#PCBa>9s&JD3Jdws#l)2;O?uBkm|ePUvv zSHmtvCqP9(*h;E&;T+jE7CWU|(RBND7YUT&WOTk-kml!4T1JHbhs)Ye=c%9JUvH@a zX!xhLPLjFuP_U=gtEfh3VCfn<(Z;g;2_uE!SL-vi163)u*z#2gL6vDgikN1G#aUwp z!NM5F`C0w$R^m_jhQ(qr*le!V`=PYIA4-tLf^o5gu~#rJvH$ZW{dJ#y+1ak}4Mfd269 z6#axrgIz*l79Vg6!o{Ck=Py7t#XYmjp8K@*ZF}Mc&#CIZvC(Rykqs|-Yp--+;L#B| z5sY9~Hha3Zf_nuqG+fw^onK3+)KTVQhJ7!Dy|9CIW&^-{(32id z4oxpOE;q1WFZp1ElNwpZITyg>ArUy2s17=KAY!KM+-udl=8&kO=n3mXHPh0wn(#=ODGBS{! zYz}v%`K}$gHXdK8u>mKi94W^<84SC!1Vn`A)&=eA>l!n-saxSZ(vD+Odd`)pX-gWIhBk>h ze|-C}Aw#EC@Jw^@VfW!=it^-#fT#Y63H>aEx(W-AV-~OWGlX}G$lII#3|qI-6a8eqdNB`mFqbq4|xzGr(hUAxQ>&sP^TAm&KtEx zc^NA+jnLz4Q$2=zvZy*AC5%RMqe;w9lcIaY#Lqr{UoPyk82f-h{L&WD0M}d0A%#h;T?UN##4{^D`>=|Yxwn`#X~mPe=}m2Y?5xq% zb2goj*;iXc=m*;Tn04fefz5M1#iFa*D?FCnIeYf*&)P!_uGja_U$#NE$o-9q>-h`4 z*rL@&Y=#LGOz*bxrMvE_T`UbxwhE>*%0%C`ZMSv9oAo_v)%|p`<@KD1!0KBYnA!XL zAfabHJrTR6zhK0RP=9q+Rk6_TGbyH1lYJI5=k3~AbC zKOmTPx#5_c$DYnMXYD9|RA)3QpvHn#KSrkx5Caae!9mb%LxvBJ7)4Wx9jTKBKuTFt zxLIye?Iz~XAJ0)sSd~E>f3qxqIJz+=90D>rO&O1>B@*l?#m>c72mA#PCLdK*=TQcn zs6pR&Q}p~ou<}$mXHM<_U)_+qJ7(6dIM>Q6a9Vxz2{$|19CGK1mYHhtRV(G*jNVVf zWxmgR91;2t^$F#HU*H=)0{JLWO*mh92Hz(-unkGm6gp&>PmL5U(e9caIyjBwV+SkZm_EW)AHutwA}> zy&laDoBUqS3JQkFeG}t8=fi|3J^7E2E#g=6c$dJ#7xw2?`1L_1?^Th8e3o}f+_efw zuVqQ;?cTQcjIAvVIUt!HG?VF1EGe_APfnsFsf-#R&|T>i`O$Nj$?w{?>-2-tfP2^J zK!zI0QAt)+i<k&3vA$n)|oC-1%PHr6ihOV+(taV>2)Mn&n;OZ^7#iGUgoq1!Oo( zgtRK*-R|_=e14v=*r6pYSu^D?m%mw)(Iaxp1#+<%@;7x@^$mb*eYCwBhUh85B(%!t za1@-jE`Hi5=6uTAKS;F#v5GGySQ<ow`OQpBH;|G7aOKJ%%>m8GRtkxBpo$2)|Os~pk6F%HMjYW@tHos}q0sjbU?ekOBH&V(NhX{#v~_ zb>t46QP*4ext!&rx|YCrqo4L?ls&yP9h^-ATvJsWD!%kz8lJ1P3ymiI+MWy1dHp?e z)=tFCkUy~-+XoHtb_CHKHnAz~6e*q(o!;nmM|5P_f2|K+N{;*z_UvuAw^9^2Lcd9r z4=e+|BaL0HtuIEy%eJMib?BW8Q*WI&js=y*lBUPgA*Au7>ad=o%~aZt@Gm z8PSRMD!vux+>YJUM=o2%~so66u-$5TA%WKyK{jDqcs%kT7Ia|2UPkZ+JQT@=WBL$q%D z?S9#5GzpW{eKVU`F2Q81CjX#ctN&5Q%-D7Jcc<(IDF_dSP9`hdXc)o>t~pw7crIFz z9;Qffs@yb|N}1>jR-Tc-BEDi4&EECKhK8tQ8@rr!hcMEK1CfdT)@F{kKEqOCUk{}6 zYAas8f>gI+dwUM)N5sEg}1v)UG0*B)^NL+5!dL-iy*3Tgp#(}>$gaz8_= z+np^0mLeDKM=m^Gj!{XceqMSFFvQ^9Da5Amb8|gRPi}NV#*{VpCsS`hCLOi+$_?#S0OL2YM7?p;B2VtW%q;9mSnSd?FLI zP*u_Wq>I#(;$<)MP=hjI9V^Tmr@hcRP3Y+0%3Uv3!|2?6UX#@a!KuNAb^__R_7)xC zenW(jN1{z1J{2Zx%QDeIxD!^P$$AdcE=G^Ghwby& zj;qYZ$N~T~n!2`kN9-c<62I` ziHsGk9eey`HEa}Vr>0V(*NtZNXUY4E(&%2!P%?*+5k1UyO>P>vgkX9R+sXU@tPuk--#5?3j$8&HkYwok&~y5Y)5k zTCNgPCH&pLwSL4SFKX({^zzTBC69F=^OVZ6fecrqn!X#SvW_Mg=PXgltFzAr2SY@{HhEru!&CFY$=<{R-2qCZ>&}isuqD(yh|__ z+7oyie^;u@3#1;Dx>|lK#Qfq$d|=*>zqAF)8gg&b3oQE=-Ys>c{&bc_nXql;jcKwqg$*M_S{ZLvcQD`r_n&k>6ux!=$io3|#Ydof!cy(`G#3KHH z_d9os$AEOs&9Sfv3S^Pbv{iD^Y+aR@W4ZjaK-}jfx&SpK(VA49U|3FwVxf9-hmFrF6WqK`OZybQSefIWPHn==0W6>+_ zMNXfC;2q5*)%40;qMD-a)Lx|EV8(6wcL?VeiC|(-fzL}AxbHLp8kMF7g$hcoTXxAb z3EDxzD>4B|>_r56DF=IYxdJ>arj^q?b%XZ%;y(M_SdA0z_dmZ$KZ)wF`0LZuis!=Q^e*yfCo)=W~ zR?YRzmome?*U#^UM&B0snwK3ML)b6H7HXc?G;D13yM1(-eTdPRBWHB_9@8HGaMb|< zz*8#4wXs3?>w>B312&T^6xH^1#-T(b24#4XtY*a-_`ZY&qcmP4bVqc8s;UMM?aR|P z8U|NPs~y3E^d}F6mK`o-u&E|@r=#{K8a#`(>2WE!e&FD{Ipfv+aUV{2vtjg%wGrX$ z59elO(n|0r>MuhWz|=piqaTf{oyA7U2HY99bFUW8qxKYQ%NLWZFpZw4YBSAxjuE+n zJ6-84{smOYv|$4N6_t7QTIOzJqY?)aW0zcUG|LOPpN7u|Q|CrgyNwkXEp2m-$BMU-FE8s zY5JgFgSHZtfjVZXzCUK=s=aRsqf=bvodmAmP&&C5u;EI-_zzRD`}l2#CWJ(#EvF{? z)ps{%>D!)Xdc>BSbeTC<6%nVFDVNR-Eu+}E;e2+=%@Kb|4vAEFfUmc_HYybL%tRKP z@IsEYcbOBmY3qC+ReSzU{?lIos$`PPMew7c_lRY0W%oP1D2;Q^696@9@(O8&~Gfc0=hLUcv-!heNH--Z7C-;lsWT9KZ~iu;2s z%eCJ*kLnS<3qPmWw4G)x4APSlsODE#V-*gqW%c}X+$=(;diZG29>X!(utLos_cscqQCoG5BBK!sE-C?SfcC`w1D4v1AXOvI`9XX# zq@jP%8z<8O)t}4zRV_(HMb79GQ? zFaBguDZ_A<9{CY$uvj)F!4W%i0=UnT(fZYkQ<$tA*`>%NAvKhr6FKopzu z=R#x>LF9{fQ?NyHIZi?956JH*bJDjf}WDOtv0 zJ1^1|lKSSyQft06@TOcI!(-B;%=vEtt5Bbi>2ks|+sFoEng!9Em!R^u;E3&+?Sbj< zA+Jx=^aWz3gdAtU0L$Fi;MuY5 zwvM&;nm%QUDsp{u3Z2Gim==^e2oWWp$(X)qE3pd5vw8O0W`*3{%hhocTT}>X;-y4w zNf>T?+VDBg-EfC@7Eh#AW;oCdTxx$+ron-pRgLU+C2dH5QoIwg^~xhe`$eFOyXk)= zk~erj^vST!5G{-zE9IjTP;<<=6O{K1_y0}F|LbkP9D0Yx_OX%_Zp`4vGDd;a$FkZv zCl(LsO_l^7J|6Cmk70i~s~-&_I02-aCm~-RBmaX0NMARaF#5>*(n4IfvQmtm)dMnV zxb;6b;D2Bi{%)PFdxLo8htgvU2Ks j} \phi_{3}(R_{ij}, R_{ik}, Z_{i}) \\ -Z_i = \sum_{m \ne i} f(R_{im}) \qquad +E & = & \sum_{j \ne i} \phi_{2}(R_{ij}, Z_{i}) + \sum_{j \ne i} \sum_{k \ne i,k > j} \phi_{3}(R_{ij}, R_{ik}, Z_{i}) \\ +\phi_{2}(r, Z) & = & A\left[\left(\frac{B}{r}\right)^{\rho} - e^{-\beta Z^2}\right]exp{\left(\frac{\sigma}{r-a}\right)} \\ +\phi_{3}(R_{ij}, R_{ik}, Z_i) & = & exp{\left(\frac{\gamma}{R_{ij}-a}\right)}exp{\left(\frac{\gamma}{R_{ik}-a}\right)}h(cos\theta_{ijk},Z_i) \\ +Z_i & = & \sum_{m \ne i} f(R_{im}) \qquad f(r) = \begin{cases} 1 & \quad ra \end{cases} \\ -\phi_{2}(r, Z) = A\left[\left(\frac{B}{r}\right)^{\rho} - e^{-\beta Z^2}\right]exp{\left(\frac{\sigma}{r-a}\right)} \\ -\phi_{3}(R_{ij}, R_{ik}, Z_i) = exp{\left(\frac{\gamma}{R_{ij}-a}\right)}exp{\left(\frac{\gamma}{R_{ik}-a}\right)}h(cos\theta_{ijk},Z_i) \\ -h(l,Z) = \lambda [(1-e^{-Q(Z)(l+\tau(Z))^2}) + \eta Q(Z)(l+\tau(Z))^2 ] \\ -Q(Z) = Q_0 e^{-\mu Z} \qquad \tau(Z) = u_1 + u_2 (u_3 e^{-u_4 Z} - e^{-2u_4 Z}) +h(l,Z) & = & \lambda [(1-e^{-Q(Z)(l+\tau(Z))^2}) + \eta Q(Z)(l+\tau(Z))^2 ] \\ +Q(Z) & = & Q_0 e^{-\mu Z} \qquad \tau(Z) = u_1 + u_2 (u_3 e^{-u_4 Z} - e^{-2u_4 Z}) \end{eqnarray*} \end{document} From 4e7b605fa19fa221a45310e555f404ecfaf1be32 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 19 Sep 2011 22:49:18 +0000 Subject: [PATCH 140/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6997 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/GPU/gpu_extra.h | 12 ++++++------ src/pointers.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/GPU/gpu_extra.h b/src/GPU/gpu_extra.h index 30faef139d..9fa2d83a12 100644 --- a/src/GPU/gpu_extra.h +++ b/src/GPU/gpu_extra.h @@ -28,17 +28,17 @@ namespace GPU_EXTRA { MPI_Allreduce(&error_flag, &all_success, 1, MPI_INT, MPI_MIN, world); if (all_success != 0) { if (all_success == -1) - error->all("Accelerated style in input script but no fix gpu."); + error->all("Accelerated style in input script but no fix gpu"); else if (all_success == -2) - error->all("Could not find/initialize a specified accelerator device."); + error->all("Could not find/initialize a specified accelerator device"); else if (all_success == -3) - error->all("Insufficient memory on accelerator."); + error->all("Insufficient memory on accelerator"); else if (all_success == -4) - error->all("GPU library not compiled for this accelerator."); + error->all("GPU library not compiled for this accelerator"); else if (all_success == -5) - error->all("Double precision is not supported on this accelerator."); + error->all("Double precision is not supported on this accelerator"); else - error->all("Unknown error in GPU library."); + error->all("Unknown error in GPU library"); } } diff --git a/src/pointers.h b/src/pointers.h index 59afc88139..f2f2215b8b 100644 --- a/src/pointers.h +++ b/src/pointers.h @@ -16,7 +16,7 @@ // every LAMMPS class inherits from Pointers to access lammps.h ptrs // these variables are auto-initialized by Pointer class constructor // *& variables are really pointers to the pointers in lammps.h -// & enables them to be accessed directly in any class, e.g. error->all() +// & enables them to be accessed directly in any class, e.g. atom->x #ifndef LMP_POINTERS_H #define LMP_POINTERS_H From 1ab03c7ee0031a333ad911c5bfcbb24fe917f30a Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 13:57:46 +0000 Subject: [PATCH 141/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6998 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/msi2lmp/README | 9 +++ tools/msi2lmp/TriclinicModification.pdf | Bin 0 -> 78328 bytes tools/msi2lmp/src/GetParameters.c | 4 +- tools/msi2lmp/src/Makefile | 2 +- tools/msi2lmp/src/Msi2LMP2.h | 4 ++ tools/msi2lmp/src/ReadCarFile.c | 77 +++++++++++++++++++----- tools/msi2lmp/src/WriteDataFile.c | 11 ++-- tools/msi2lmp/src/WriteDataFile05.c | 35 ++++++++--- tools/msi2lmp/src/msi2lmp.c | 19 +++--- 9 files changed, 122 insertions(+), 39 deletions(-) create mode 100644 tools/msi2lmp/TriclinicModification.pdf diff --git a/tools/msi2lmp/README b/tools/msi2lmp/README index a70a67b84b..ac565ce47e 100644 --- a/tools/msi2lmp/README +++ b/tools/msi2lmp/README @@ -1,3 +1,12 @@ +Stephanie Teich-McGoldrick (Sandai) is the current maintainer +of the msi2lmp tool. She can be contacted at steichm at sandia.gov + +23 Sep 2011 + +added support for triclinic boxes +see msi2lmp/TriclinicModification.pdf doc for details + +----------------------------- msi2lmp V3.6 4/10/2005 diff --git a/tools/msi2lmp/TriclinicModification.pdf b/tools/msi2lmp/TriclinicModification.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a88bb902f0da05d2ea9e776986c6732e0e37b480 GIT binary patch literal 78328 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 highest) highest = atoms[m].x[k]; + for ( m = 1; m < total_no_atoms; m++) { + if (atoms[m].x[k] < lowest) lowest = atoms[m].x[k]; + if (atoms[m].x[k] > highest) highest = atoms[m].x[k]; + } + pbc[k] = lowest; + pbc[k+3] = highest; } - pbc[k] = lowest; - pbc[k+3] = highest; - } + } + else { + printf("Code only works for periodic systems with triclinic boxes"); + exit(2); + } + } else { - for (k=0; k < 3; k++) { - pbc[k+3] = pbc[k]; - pbc[k] = 0.0; - } + // Modified lines 176 - 201 Oct 5th 2010 + if (TriclinicFlag == 0) { + for (k=0; k < 3; k++) { + pbc[k+3] = pbc[k]; + pbc[k] = 0.0; + } + } + else { + sq_c = pbc[2]*pbc[2]; + cos_alpha = cos(pbc[3]*3.14159265358979323846/180.0); + cos_gamma = cos(pbc[5]*3.14159265358979323846/180.0); + sin_gamma = sin(pbc[5]*3.14159265358979323846/180.0); + cos_beta = cos(pbc[4]*3.14159265358979323846/180.0); + sin_beta = sin(pbc[4]*3.14159265358979323846/180.0); + printf("pbc[3] %lf pbc[4] %lf pbc[5] %lf\n", pbc[3] ,pbc[4] ,pbc[5]); + printf("cos_alpha %lf cos_beta %lf cos_gamma %lf\n", cos_alpha ,cos_beta ,cos_gamma); + A = pbc[0]; + B = pbc[1]; + C = pbc[2]; + + + pbc[0] = A; + pbc[1] = B*sin_gamma; + pbc[2] = sqrt(sq_c * sin_beta*sin_beta - C*(cos_alpha-cos_gamma*cos_beta)/sin_gamma); + pbc[3] = B * cos_gamma; // This is xy SLTM + pbc[4] = C * cos_beta; // This is xz SLTM + pbc[5] = C*(cos_alpha-cos_gamma*cos_beta)/sin_gamma; // This is yz SLTM + } + + + } /* Close .car file */ diff --git a/tools/msi2lmp/src/WriteDataFile.c b/tools/msi2lmp/src/WriteDataFile.c index 050240dcc2..cca6db09d8 100644 --- a/tools/msi2lmp/src/WriteDataFile.c +++ b/tools/msi2lmp/src/WriteDataFile.c @@ -37,11 +37,14 @@ void WriteDataFile(FILE *DatF,char *nameroot,int forcefield) if (no_oop_types > 0) fprintf (DatF, " %3d improper types\n", no_oop_types); } - + + fprintf(DatF, "\n"); - fprintf(DatF, " %15.9f %15.9f xlo xhi\n", pbc[0], pbc[3]); - fprintf(DatF, " %15.9f %15.9f ylo yhi\n", pbc[1], pbc[4]); - fprintf(DatF, " %15.9f %15.9f zlo zhi\n", pbc[2], pbc[5]); + fprintf(DatF, " %15.9f %15.9f xlo xhi\n", 0.0, pbc[0]); + fprintf(DatF, " %15.9f %15.9f ylo yhi\n", 0.0, pbc[1]); + fprintf(DatF, " %15.9f %15.9f zlo zhi\n", 0.0, pbc[2]); + fprintf(DatF, " %15.9f %15.9f %15.9f xy xz yz\n", pbc[3], pbc[4], pbc[5]); + /* MASSES */ diff --git a/tools/msi2lmp/src/WriteDataFile05.c b/tools/msi2lmp/src/WriteDataFile05.c index ac195803b3..504314e12b 100644 --- a/tools/msi2lmp/src/WriteDataFile05.c +++ b/tools/msi2lmp/src/WriteDataFile05.c @@ -49,12 +49,25 @@ void WriteDataFile05(char *nameroot,int forcefield) if (no_oop_types > 0) fprintf (DatF, " %3d improper types\n", no_oop_types); } - - fprintf(DatF, "\n"); - fprintf(DatF, " %15.9f %15.9f xlo xhi\n", pbc[0], pbc[3]); - fprintf(DatF, " %15.9f %15.9f ylo yhi\n", pbc[1], pbc[4]); - fprintf(DatF, " %15.9f %15.9f zlo zhi\n", pbc[2], pbc[5]); - + + + // Modified by SLTM to print out triclinic box types 10/05/10 - lines 56-68 + + if (TriclinicFlag == 0) { + fprintf(DatF, "\n"); + fprintf(DatF, " %15.9f %15.9f xlo xhi\n", pbc[0], pbc[3]); + fprintf(DatF, " %15.9f %15.9f ylo yhi\n", pbc[1], pbc[4]); + fprintf(DatF, " %15.9f %15.9f zlo zhi\n", pbc[2], pbc[5]); + } + else { + fprintf(DatF, "\n"); + fprintf(DatF, " %15.9f %15.9f xlo xhi\n", 0.0, pbc[0]); + fprintf(DatF, " %15.9f %15.9f ylo yhi\n", 0.0, pbc[1]); + fprintf(DatF, " %15.9f %15.9f zlo zhi\n", 0.0, pbc[2]); + fprintf(DatF, " %15.9f %15.9f %15.9f xy xz yz\n", pbc[3], pbc[4], pbc[5]); + } + + /* MASSES */ @@ -113,7 +126,10 @@ void WriteDataFile05(char *nameroot,int forcefield) for (i=0; i < no_dihedral_types; i++) { fprintf(DatF, "%3i ", i+1); for ( j = 0; j < m; j++) - fprintf(DatF, "%10.4f ", dihedraltypes[i].params[j]); + // Modified on 10/05/2010 by STLM to match with lammps reading in integers for the all but the first coefficients + if (j == 0) + fprintf(DatF, "%10.4f ", dihedraltypes[i].params[j]); + else fprintf(DatF, "%10.0f ", dihedraltypes[i].params[j]); fprintf(DatF,"\n"); } fprintf(DatF, "\n"); @@ -124,7 +140,10 @@ void WriteDataFile05(char *nameroot,int forcefield) for (i=0; i < no_oop_types; i++) { fprintf(DatF, "%3i ", i+1); for ( j = 0; j < 3; j++) - fprintf(DatF, "%10.4f ", ooptypes[i].params[j]); + // Modified on 10/05/2010 by STLM to match with lammps reading in integers for the all but the first coefficients + if (j == 0) + fprintf(DatF, "%10.4f ", ooptypes[i].params[j]); + else fprintf(DatF, "%10.0f ", ooptypes[i].params[j]); fprintf(DatF, "\n"); } fprintf(DatF, "\n"); diff --git a/tools/msi2lmp/src/msi2lmp.c b/tools/msi2lmp/src/msi2lmp.c index 1a7508a1bc..af687d0dea 100644 --- a/tools/msi2lmp/src/msi2lmp.c +++ b/tools/msi2lmp/src/msi2lmp.c @@ -131,7 +131,7 @@ int main (int argc, char *argv[]) extern void CheckLists(); extern void WriteDataFile(FILE *,char *,int); - + outv = 2005; pflag = 1; forcefield = 1; /* Variable that identifies forcefield to use */ @@ -140,9 +140,9 @@ int main (int argc, char *argv[]) frc_dir_name = (char *) calloc(160,sizeof(char)); frc_dir_name = getenv("BIOSYM_LIBRARY"); - + if (frc_dir_name == NULL) { - frc_file_name = strcpy(frc_file_name,"./cvff.frc"); + frc_file_name = strcpy(frc_file_name,"../biosym_frc_files/clayff.frc"); } else { for (i=0; i < strlen(frc_dir_name); i++) @@ -150,12 +150,14 @@ int main (int argc, char *argv[]) frc_file_name = strcat(frc_file_name,"/cvff.frc"); } + + if (argc < 2) { /* If no rootname was supplied, prompt for it */ fprintf(stderr,"The rootname of the .car and .mdf files must be entered\n"); } else /* rootname was supplied as first argument, copy to rootname */ sprintf(rootname,"%s",argv[1]); - + n = 2; while (n < argc) { if (strcmp(argv[n],"-class") == 0) { @@ -223,20 +225,21 @@ int main (int argc, char *argv[]) } /* Read in .car file */ - + printf("I am before read car file\n"); ReadCarFile(); - + printf("I am after read car file\n"); /*Read in .mdf file */ ReadMdfFile(); - + printf("I am after read mdf file\n"); /* Define bonds, angles, etc...*/ if (pflag > 0) fprintf(stderr,"\n Building internal coordinate lists \n"); MakeLists(); /* Read .frc file into memory */ - + + // Commented out to create conversion file suitable for non-orthogonal boxes Sept 13, 2010 SLTM if (pflag > 0) fprintf(stderr,"\n Reading forcefield file \n"); ReadFrcFile(); From cd6cff618686744384fbc2e4e0c5fcd1f79a2b67 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 13:57:54 +0000 Subject: [PATCH 142/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6999 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/msi2lmp/biosym_frc_files/clayff.frc | 154 ++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 tools/msi2lmp/biosym_frc_files/clayff.frc diff --git a/tools/msi2lmp/biosym_frc_files/clayff.frc b/tools/msi2lmp/biosym_frc_files/clayff.frc new file mode 100644 index 0000000000..bdc9c2c004 --- /dev/null +++ b/tools/msi2lmp/biosym_frc_files/clayff.frc @@ -0,0 +1,154 @@ +!CLAYFF forcefield + +#atom_types cvff + +!Ver Ref Type Mass Element Connections Comment +!---- --- ---- ---------- ------- ----------------------------------------- + 1.0 1 st 28.08550 Si 4 + 1.0 1 ao 26.98154 Al 6 + 1.0 1 at 26.98154 Al 4 + 1.0 1 mgo 24.30500 Mg 6 + 1.0 1 cao 40.08000 Ca 6 + 1.0 1 feo 55.84700 Fe 6 + 1.0 1 lio 6.941000 Li 6 + 1.0 1 ob 15.99940 O 2 + 1.0 1 obss 15.99940 O 3 + 1.0 1 obts 15.99940 O 2 + 1.0 1 obos 15.99940 O 2 + 1.0 1 ohs 15.99940 O 2 + 1.0 1 oh 15.99940 O 2 + 1.0 1 oh- 15.99940 O 1 + 1.0 1 o* 15.99940 O 2 + 1.0 1 ho 1.007970 H 1 + 1.0 1 h* 1.007970 H 1 + 1.0 1 Na 22.99000 Na 0 + 1.0 1 K 39.10 K 0 + 1.0 1 Cs 132.9100 Cs 0 + 1.0 1 Ca 40.07980 Ca 0 + 1.0 1 Ba 137.3300 Ba 0 + 1.0 1 Mg 24.3050 Mg 0 + 1.0 1 Sr 87.6200 Sr 0 + 1.0 1 Pb 207.2000 Pb 0 + 1.0 1 Cl 35.45300 Cl 0 + + +#equivalence cvff + +> Equivalence table for any variant of cvff + +! Equivalences +! ----------------------------------------- +!Ver Ref Type NonB Bond Angle Torsion OOP +!---- --- ---- ---- ---- ----- ------- ---- + 1.0 1 h h h h h h + + + +#auto_equivalence cvff_auto + +! Equivalences +! ----------------------------------------- +!Ver Ref Type NonB Bond Bond Angle Angle Torsion Torsion OOP OOP +! Inct End atom Apex atom End Atoms Center Atoms End Atom Center Atom +!---- --- ---- ---- ------ ---- ---------- --------- --------- ----------- -------- ----------- + 2.0 18 h h h h_ h_ h_ h_ h_ h_ h_ + + + +#hbond_definition cvff + + +#morse_bond cvff + +> E = D * (1 - exp(-ALPHA*(R - R0)))^2 + +!Ver Ref I J R0 D ALPHA +!---- --- ---- ---- ------- -------- ------- + 2.3 23 no o- 1.2178 140.2486 2.0000 + + + +#quadratic_bond cvff + +> E = K2 * (R - R0)^2 + +!Ver Ref I J R0 K2 +!---- --- ---- ---- ------- -------- + 2.1 28 oh ho 1.0000 553.9350 + 2.1 28 ohs ho 1.0000 553.9350 + + +#quadratic_angle cvff + +> E = K2 * (Theta - Theta0)^2 + +!Ver Ref I J K Theta0 K2 +!---- --- ---- ---- ---- -------- ------- + 2.3 23 cp cp c' 120.0000 34.6799 + + + +#torsion_1 cvff_auto + +> E = Kphi * [ 1 + cos(n*Phi - Phi0) ] + +!Ver Ref I J K L Kphi n Phi0 +!---- --- ---- ---- ---- ---- ------- ------ ------- + 2.0 18 * c_ n3n_ * 0.0500 3 0. + + + +#out_of_plane cvff_auto + +> E = Kchi * [ 1 + cos(n*Chi - Chi0) ] + +!Ver Ref I J K L Kchi n Chi0 +!---- --- ---- ---- ---- ---- ------- ------ ------- + 2.0 18 * c'_ * * 10.0000 2 180.0000 + + +#nonbond(12-6) cvff + +@type A-B +@combination geometric + +> E = Aij/r^12 - Bij/r^6 +> where Aij = sqrt( Ai * Aj ) +> Bij = sqrt( Bi * Bj ) + +!Ver Ref I A B +!---- --- ---- ----------- ----------- + 1.0 1 st 12.3645 0.00954 + 1.0 1 ao 196.1446 0.03230 + 1.0 1 at 12.3645 0.00954 + 1.0 1 mgo 1636.3265 0.07688 + 1.0 1 cao 17814.73 0.5987 + 1.0 1 feo 702.54 0.0504 + 1.0 1 lio 112.01 0.0201 + 1.0 1 ob 629358.0000 625.50000 + 1.0 1 obss 629358.0000 625.50000 + 1.0 1 obts 629358.0000 625.50000 + 1.0 1 obos 629358.0000 625.50000 + 1.0 1 ohs 629358.0000 625.50000 + 1.0 1 oh 629358.0000 625.50000 + 1.0 1 oh- 629358.0000 625.50000 + 1.0 1 o* 629358.0000 625.50000 + 1.0 1 ho 0.00000001 0.00000 + 1.0 1 h* 0.00000001 0.00000 + 1.0 1 Na 14763.1719 87.65132 + 1.0 1 K 754506.86 549.37 + 1.0 1 Cs 3998193.96 1264.63 + 1.0 1 Ca 125966.6068 224.46969 + 1.0 1 Ba 1799606.56 582.25 + 1.0 1 Mg 1369.00 69.22 + 1.0 1 Sr 1185860.37 688.73 + 1.0 1 Pb 861150.71 638.08 + 1.0 1 Cl 21081006.97 2905.31 + + +#bond_increments cvff + +!Ver Ref I J DeltaIJ DeltaJI +!---- --- ---- ---- ------- ------- + 2.3 23 no o- 0.1684 -0.1684 + From 1ba435ee186559d896e1fd54795b1391a4f4ee5b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 13:58:33 +0000 Subject: [PATCH 143/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7000 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/dump_cfg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp index 3e7d83eff2..eb1732e93f 100755 --- a/src/dump_cfg.cpp +++ b/src/dump_cfg.cpp @@ -217,7 +217,7 @@ void DumpCFG::write_data(int n, double *mybuf) fprintf(fp,vformat[j],static_cast (rbuf[i][j])); else fprintf(fp,vformat[j],rbuf[i][j]); } - else + else { // Unwrapped scaled coordinates are shifted to // center of expanded box, to prevent @@ -234,7 +234,7 @@ void DumpCFG::write_data(int n, double *mybuf) fprintf(fp,vformat[j],static_cast (rbuf[i][j])); else fprintf(fp,vformat[j],rbuf[i][j]); } - + } fprintf(fp,"\n"); } } From 2d99de131d05abd408d6f216cac0309d360a96e0 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 14:01:19 +0000 Subject: [PATCH 144/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7001 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 719b5561f4..3969e11c17 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "17 Sep 2011" +#define LAMMPS_VERSION "23 Sep 2011" From 19e8c92a906e96200926345a13b591630c4c3823 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 18:06:55 +0000 Subject: [PATCH 145/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7003 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/ASPHERE/compute_erotate_asphere.cpp | 6 +- src/ASPHERE/compute_temp_asphere.cpp | 22 +- src/ASPHERE/fix_nh_asphere.cpp | 4 +- src/ASPHERE/fix_nph_asphere.cpp | 4 +- src/ASPHERE/fix_npt_asphere.cpp | 4 +- src/ASPHERE/fix_nve_asphere.cpp | 4 +- src/ASPHERE/fix_nvt_asphere.cpp | 4 +- src/ASPHERE/pair_gayberne.cpp | 23 +- src/ASPHERE/pair_resquared.cpp | 25 +- src/CLASS2/angle_class2.cpp | 10 +- src/CLASS2/bond_class2.cpp | 4 +- src/CLASS2/dihedral_class2.cpp | 21 +- src/CLASS2/improper_class2.cpp | 10 +- src/CLASS2/pair_lj_class2.cpp | 9 +- src/CLASS2/pair_lj_class2_coul_cut.cpp | 11 +- src/CLASS2/pair_lj_class2_coul_long.cpp | 13 +- src/COLLOID/fix_wall_colloid.cpp | 6 +- src/COLLOID/pair_colloid.cpp | 17 +- src/COLLOID/pair_lubricate.cpp | 19 +- src/COLLOID/pair_yukawa_colloid.cpp | 4 +- src/DIPOLE/atom_vec_dipole.cpp | 6 +- src/DIPOLE/pair_dipole_cut.cpp | 11 +- src/GPU/fix_gpu.cpp | 26 +- src/GPU/gpu_extra.h | 14 +- src/GPU/pair_cg_cmm_coul_long_gpu.cpp | 11 +- src/GPU/pair_cg_cmm_coul_msm.cpp | 14 +- src/GPU/pair_cg_cmm_coul_msm_gpu.cpp | 10 +- src/GPU/pair_cg_cmm_gpu.cpp | 7 +- src/GPU/pair_coul_long_gpu.cpp | 11 +- src/GPU/pair_gayberne_gpu.cpp | 13 +- src/GPU/pair_lj96_cut_gpu.cpp | 7 +- src/GPU/pair_lj_charmm_coul_long_gpu.cpp | 11 +- src/GPU/pair_lj_class2_coul_long_gpu.cpp | 11 +- src/GPU/pair_lj_class2_gpu.cpp | 7 +- src/GPU/pair_lj_cut_coul_cut_gpu.cpp | 9 +- src/GPU/pair_lj_cut_coul_long_gpu.cpp | 11 +- src/GPU/pair_lj_cut_gpu.cpp | 7 +- src/GPU/pair_lj_cut_tgpu.cpp | 7 +- src/GPU/pair_lj_expand_gpu.cpp | 7 +- src/GPU/pair_morse_gpu.cpp | 7 +- src/GPU/pair_resquared_gpu.cpp | 13 +- src/GPU/pppm_gpu.cpp | 11 +- src/GRANULAR/fix_freeze.cpp | 6 +- src/GRANULAR/fix_pour.cpp | 56 +-- src/GRANULAR/fix_wall_gran.cpp | 47 +- src/GRANULAR/pair_gran_hertz_history.cpp | 7 +- src/GRANULAR/pair_gran_hooke.cpp | 3 - src/GRANULAR/pair_gran_hooke_history.cpp | 17 +- src/KSPACE/ewald.cpp | 23 +- src/KSPACE/fft3d_wrap.cpp | 2 +- src/KSPACE/pair_born_coul_long.cpp | 17 +- src/KSPACE/pair_buck_coul_long.cpp | 17 +- src/KSPACE/pair_coul_long.cpp | 15 +- src/KSPACE/pair_lj_charmm_coul_long.cpp | 19 +- src/KSPACE/pair_lj_cut_coul_long.cpp | 15 +- src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp | 21 +- src/KSPACE/pppm.cpp | 47 +- src/KSPACE/pppm_cg.cpp | 4 +- src/KSPACE/pppm_tip4p.cpp | 6 +- src/KSPACE/remap_wrap.cpp | 2 +- src/MANYBODY/fix_qeq_comb.cpp | 19 +- src/MANYBODY/pair_adp.cpp | 17 +- src/MANYBODY/pair_airebo.cpp | 23 +- src/MANYBODY/pair_comb.cpp | 32 +- src/MANYBODY/pair_eam.cpp | 11 +- src/MANYBODY/pair_eam_alloy.cpp | 12 +- src/MANYBODY/pair_eam_fs.cpp | 12 +- src/MANYBODY/pair_eim.cpp | 23 +- src/MANYBODY/pair_rebo.cpp | 2 +- src/MANYBODY/pair_sw.cpp | 24 +- src/MANYBODY/pair_tersoff.cpp | 24 +- src/MANYBODY/pair_tersoff_zbl.cpp | 8 +- src/MC/fix_bond_break.cpp | 25 +- src/MC/fix_bond_create.cpp | 51 +-- src/MC/fix_bond_swap.cpp | 24 +- src/MC/fix_gcmc.cpp | 32 +- src/MC/pair_dsmc.cpp | 19 +- src/MEAM/pair_meam.cpp | 39 +- src/MOLECULE/angle_charmm.cpp | 4 +- src/MOLECULE/angle_cosine.cpp | 4 +- src/MOLECULE/angle_cosine_periodic.cpp | 6 +- src/MOLECULE/angle_cosine_squared.cpp | 4 +- src/MOLECULE/angle_harmonic.cpp | 4 +- src/MOLECULE/angle_hybrid.cpp | 15 +- src/MOLECULE/angle_table.cpp | 25 +- src/MOLECULE/atom_vec_angle.cpp | 9 +- src/MOLECULE/atom_vec_bond.cpp | 9 +- src/MOLECULE/atom_vec_full.cpp | 9 +- src/MOLECULE/atom_vec_molecular.cpp | 9 +- src/MOLECULE/bond_fene.cpp | 14 +- src/MOLECULE/bond_fene_expand.cpp | 14 +- src/MOLECULE/bond_harmonic.cpp | 4 +- src/MOLECULE/bond_morse.cpp | 4 +- src/MOLECULE/bond_nonlinear.cpp | 4 +- src/MOLECULE/bond_quartic.cpp | 14 +- src/MOLECULE/bond_table.cpp | 25 +- src/MOLECULE/dihedral_charmm.cpp | 14 +- src/MOLECULE/dihedral_harmonic.cpp | 10 +- src/MOLECULE/dihedral_helix.cpp | 9 +- src/MOLECULE/dihedral_hybrid.cpp | 8 +- src/MOLECULE/dihedral_multi_harmonic.cpp | 9 +- src/MOLECULE/dihedral_opls.cpp | 9 +- src/MOLECULE/improper_cvff.cpp | 6 +- src/MOLECULE/improper_harmonic.cpp | 6 +- src/MOLECULE/improper_hybrid.cpp | 8 +- src/MOLECULE/improper_umbrella.cpp | 6 +- src/MOLECULE/pair_hbond_dreiding_lj.cpp | 23 +- src/MOLECULE/pair_hbond_dreiding_morse.cpp | 21 +- src/MOLECULE/pair_lj_charmm_coul_charmm.cpp | 13 +- src/Makefile | 4 + src/OPT/pair_eam_opt.cpp | 3 - src/OPT/pair_lj_charmm_coul_long_opt.cpp | 3 - src/PERI/atom_vec_peri.cpp | 10 +- src/PERI/compute_damage_atom.cpp | 6 +- src/PERI/fix_peri_neigh.cpp | 5 +- src/PERI/pair_peri_lps.cpp | 23 +- src/PERI/pair_peri_pmb.cpp | 21 +- src/POEMS/fix_poems.cpp | 41 +- src/REAX/fix_reax_bonds.cpp | 10 +- src/REAX/pair_reax.cpp | 30 +- src/REPLICA/compute_event_displace.cpp | 8 +- src/REPLICA/fix_event.cpp | 2 +- src/REPLICA/fix_event_prd.cpp | 2 +- src/REPLICA/fix_event_tad.cpp | 2 +- src/REPLICA/fix_neb.cpp | 11 +- src/REPLICA/neb.cpp | 34 +- src/REPLICA/prd.cpp | 46 +- src/REPLICA/tad.cpp | 46 +- src/REPLICA/temper.cpp | 18 +- src/SHOCK/fix_append_atoms.cpp | 66 +-- src/SHOCK/fix_msst.cpp | 36 +- src/SHOCK/fix_nphug.cpp | 18 +- src/SHOCK/fix_wall_piston.cpp | 54 +-- src/SRD/fix_srd.cpp | 141 +++--- src/SRD/fix_wall_srd.cpp | 30 +- src/USER-ATC/fix_atc.cpp | 4 +- src/USER-AWPMD/atom_vec_wavepacket.cpp | 8 +- src/USER-AWPMD/fix_nve_awpmd.cpp | 4 +- src/USER-AWPMD/pair_awpmd_cut.cpp | 35 +- src/USER-CG-CMM/angle_cg_cmm.cpp | 6 +- src/USER-CG-CMM/pair_cg_cmm_coul_cut.cpp | 11 +- src/USER-CG-CMM/pair_cg_cmm_coul_long.cpp | 14 +- src/USER-CG-CMM/pair_cmm_common.cpp | 21 +- src/USER-CUDA/atom_vec_angle_cuda.cpp | 2 +- src/USER-CUDA/atom_vec_atomic_cuda.cpp | 2 +- src/USER-CUDA/atom_vec_charge_cuda.cpp | 2 +- src/USER-CUDA/atom_vec_full_cuda.cpp | 2 +- src/USER-CUDA/comm_cuda.cpp | 9 +- src/USER-CUDA/compute_pressure_cuda.cpp | 6 +- src/USER-CUDA/compute_temp_cuda.cpp | 6 +- src/USER-CUDA/compute_temp_partial_cuda.cpp | 8 +- src/USER-CUDA/cuda.cpp | 18 +- src/USER-CUDA/cuda_neigh_list.cpp | 2 +- src/USER-CUDA/domain_cuda.cpp | 10 +- src/USER-CUDA/fft3d_cuda.cpp | 3 +- src/USER-CUDA/fft3d_wrap_cuda.cpp | 2 +- src/USER-CUDA/fix_addforce_cuda.cpp | 12 +- src/USER-CUDA/fix_aveforce_cuda.cpp | 12 +- src/USER-CUDA/fix_enforce2d_cuda.cpp | 12 +- src/USER-CUDA/fix_freeze_cuda.cpp | 8 +- src/USER-CUDA/fix_gravity_cuda.cpp | 14 +- src/USER-CUDA/fix_nh_cuda.cpp | 139 +++--- src/USER-CUDA/fix_npt_cuda.cpp | 6 +- src/USER-CUDA/fix_nve_cuda.cpp | 4 +- src/USER-CUDA/fix_nvt_cuda.cpp | 4 +- src/USER-CUDA/fix_set_force_cuda.cpp | 4 +- src/USER-CUDA/fix_shake_cuda.cpp | 52 ++- src/USER-CUDA/fix_temp_berendsen_cuda.cpp | 20 +- src/USER-CUDA/fix_temp_rescale_cuda.cpp | 22 +- src/USER-CUDA/fix_temp_rescale_limit_cuda.cpp | 26 +- src/USER-CUDA/fix_viscous_cuda.cpp | 2 +- src/USER-CUDA/modify_cuda.cpp | 7 +- src/USER-CUDA/neigh_full_cuda.cpp | 4 +- src/USER-CUDA/neighbor_cuda.cpp | 7 +- src/USER-CUDA/pair_born_coul_long_cuda.cpp | 13 +- src/USER-CUDA/pair_buck_coul_cut_cuda.cpp | 11 +- src/USER-CUDA/pair_buck_coul_long_cuda.cpp | 13 +- src/USER-CUDA/pair_buck_cuda.cpp | 11 +- src/USER-CUDA/pair_cg_cmm_coul_cut_cuda.cpp | 7 +- src/USER-CUDA/pair_cg_cmm_coul_debye_cuda.cpp | 7 +- src/USER-CUDA/pair_cg_cmm_coul_long_cuda.cpp | 7 +- src/USER-CUDA/pair_cg_cmm_cuda.cpp | 5 +- src/USER-CUDA/pair_eam_alloy_cuda.cpp | 14 +- src/USER-CUDA/pair_eam_cuda.cpp | 5 +- src/USER-CUDA/pair_eam_fs_cuda.cpp | 14 +- src/USER-CUDA/pair_gran_hooke_cuda.cpp | 9 +- src/USER-CUDA/pair_lj96_cut_cuda.cpp | 5 +- .../pair_lj_charmm_coul_charmm_cuda.cpp | 9 +- ...ir_lj_charmm_coul_charmm_implicit_cuda.cpp | 9 +- .../pair_lj_charmm_coul_long_cuda.cpp | 13 +- .../pair_lj_class2_coul_cut_cuda.cpp | 7 +- .../pair_lj_class2_coul_long_cuda.cpp | 13 +- src/USER-CUDA/pair_lj_class2_cuda.cpp | 5 +- src/USER-CUDA/pair_lj_cut_coul_cut_cuda.cpp | 7 +- src/USER-CUDA/pair_lj_cut_coul_debye_cuda.cpp | 7 +- src/USER-CUDA/pair_lj_cut_coul_long_cuda.cpp | 13 +- src/USER-CUDA/pair_lj_cut_cuda.cpp | 5 +- .../pair_lj_cut_experimental_cuda.cpp | 5 +- src/USER-CUDA/pair_lj_expand_cuda.cpp | 5 +- .../pair_lj_gromacs_coul_gromacs_cuda.cpp | 9 +- src/USER-CUDA/pair_lj_gromacs_cuda.cpp | 5 +- src/USER-CUDA/pair_lj_smooth_cuda.cpp | 5 +- src/USER-CUDA/pair_morse_cuda.cpp | 5 +- src/USER-CUDA/pppm_cuda.cpp | 49 +- src/USER-CUDA/verlet_cuda.cpp | 13 +- src/USER-EFF/atom_vec_electron.cpp | 6 +- src/USER-EFF/compute_ke_atom_eff.cpp | 6 +- src/USER-EFF/compute_ke_eff.cpp | 4 +- src/USER-EFF/compute_temp_deform_eff.cpp | 8 +- src/USER-EFF/compute_temp_eff.cpp | 2 +- src/USER-EFF/compute_temp_region_eff.cpp | 8 +- src/USER-EFF/fix_nh_eff.cpp | 2 +- src/USER-EFF/fix_nph_eff.cpp | 4 +- src/USER-EFF/fix_npt_eff.cpp | 4 +- src/USER-EFF/fix_nve_eff.cpp | 2 +- src/USER-EFF/fix_nvt_eff.cpp | 4 +- src/USER-EFF/fix_nvt_sllod_eff.cpp | 10 +- src/USER-EFF/fix_temp_rescale_eff.cpp | 16 +- src/USER-EFF/pair_eff_cut.cpp | 19 +- src/USER-EWALDN/ewald_n.cpp | 16 +- src/USER-EWALDN/pair_buck_coul.cpp | 35 +- src/USER-EWALDN/pair_lj_coul.cpp | 35 +- src/USER-MISC/angle_cosine_shift.cpp | 4 +- src/USER-MISC/angle_cosine_shift_exp.cpp | 4 +- src/USER-MISC/bond_harmonic_shift.cpp | 4 +- src/USER-MISC/bond_harmonic_shift_cut.cpp | 4 +- src/USER-MISC/compute_ackland_atom.cpp | 4 +- src/USER-MISC/compute_temp_rotate.cpp | 5 +- src/USER-MISC/dihedral_cosine_shift_exp.cpp | 6 +- src/USER-MISC/fix_addtorque.cpp | 14 +- src/USER-MISC/fix_imd.cpp | 18 +- src/USER-MISC/fix_smd.cpp | 20 +- src/USER-MISC/pair_cdeam.cpp | 20 +- src/USER-MISC/pair_dipole_sf.cpp | 11 +- src/USER-MISC/pair_edip.cpp | 24 +- src/USER-MISC/pair_lj_sf.cpp | 13 +- src/USER-REAXC/fix_qeq_reax.cpp | 29 +- src/USER-REAXC/pair_reax_c.cpp | 28 +- src/USER-SPH/atom_vec_meso.cpp | 6 +- src/USER-SPH/compute_meso_e_atom.cpp | 6 +- src/USER-SPH/compute_meso_rho_atom.cpp | 6 +- src/USER-SPH/compute_meso_t_atom.cpp | 6 +- src/USER-SPH/fix_meso.cpp | 4 +- src/USER-SPH/fix_meso_stationary.cpp | 4 +- src/USER-SPH/pair_sph_heatconduction.cpp | 11 +- src/USER-SPH/pair_sph_idealgas.cpp | 11 +- src/USER-SPH/pair_sph_lj.cpp | 11 +- src/USER-SPH/pair_sph_rhosum.cpp | 11 +- src/USER-SPH/pair_sph_taitwater.cpp | 11 +- src/USER-SPH/pair_sph_taitwater_morris.cpp | 11 +- src/XTC/dump_xtc.cpp | 28 +- src/angle.cpp | 4 +- src/atom.cpp | 85 ++-- src/atom_vec_atomic.cpp | 6 +- src/atom_vec_charge.cpp | 6 +- src/atom_vec_ellipsoid.cpp | 20 +- src/atom_vec_hybrid.cpp | 15 +- src/atom_vec_sphere.cpp | 14 +- src/bond.cpp | 4 +- src/bond_hybrid.cpp | 14 +- src/change_box.cpp | 16 +- src/comm.cpp | 27 +- src/compute.cpp | 29 +- src/compute_angle_local.cpp | 8 +- src/compute_atom_molecule.cpp | 42 +- src/compute_bond_local.cpp | 8 +- src/compute_centro_atom.cpp | 8 +- src/compute_cluster_atom.cpp | 13 +- src/compute_cna_atom.cpp | 19 +- src/compute_com.cpp | 2 +- src/compute_com_molecule.cpp | 6 +- src/compute_coord_atom.cpp | 8 +- src/compute_dihedral_local.cpp | 13 +- src/compute_displace_atom.cpp | 4 +- src/compute_erotate_sphere.cpp | 4 +- src/compute_group_group.cpp | 10 +- src/compute_gyration.cpp | 2 +- src/compute_gyration_molecule.cpp | 6 +- src/compute_heat_flux.cpp | 12 +- src/compute_improper_local.cpp | 8 +- src/compute_ke.cpp | 2 +- src/compute_ke_atom.cpp | 4 +- src/compute_msd.cpp | 10 +- src/compute_msd_molecule.cpp | 6 +- src/compute_pair.cpp | 12 +- src/compute_pair_local.cpp | 8 +- src/compute_pe.cpp | 8 +- src/compute_pe_atom.cpp | 6 +- src/compute_pressure.cpp | 16 +- src/compute_property_atom.cpp | 60 +-- src/compute_property_local.cpp | 58 +-- src/compute_property_molecule.cpp | 8 +- src/compute_rdf.cpp | 8 +- src/compute_reduce.cpp | 70 ++- src/compute_reduce_region.cpp | 2 +- src/compute_slice.cpp | 42 +- src/compute_stress_atom.cpp | 6 +- src/compute_temp.cpp | 2 +- src/compute_temp_com.cpp | 5 +- src/compute_temp_deform.cpp | 6 +- src/compute_temp_partial.cpp | 4 +- src/compute_temp_profile.cpp | 33 +- src/compute_temp_ramp.cpp | 17 +- src/compute_temp_region.cpp | 6 +- src/compute_temp_sphere.cpp | 20 +- src/compute_ti.cpp | 22 +- src/create_atoms.cpp | 45 +- src/create_box.cpp | 10 +- src/delete_atoms.cpp | 37 +- src/delete_bonds.cpp | 24 +- src/dihedral.cpp | 4 +- src/displace_atoms.cpp | 31 +- src/displace_box.cpp | 62 +-- src/domain.cpp | 42 +- src/dump.cpp | 45 +- src/dump_atom.cpp | 10 +- src/dump_cfg.cpp | 10 +- src/dump_custom.cpp | 168 +++---- src/dump_dcd.cpp | 22 +- src/dump_image.cpp | 209 +++++---- src/dump_local.cpp | 44 +- src/dump_xyz.cpp | 4 +- src/error.cpp | 39 +- src/error.h | 12 +- src/finish.cpp | 3 - src/fix.cpp | 12 +- src/fix_adapt.cpp | 53 ++- src/fix_addforce.cpp | 34 +- src/fix_ave_atom.cpp | 42 +- src/fix_ave_correlate.cpp | 68 +-- src/fix_ave_histo.cpp | 151 ++++--- src/fix_ave_spatial.cpp | 97 ++-- src/fix_ave_time.cpp | 96 ++-- src/fix_aveforce.cpp | 22 +- src/fix_box_relax.cpp | 111 +++-- src/fix_deform.cpp | 82 ++-- src/fix_deposit.cpp | 48 +- src/fix_drag.cpp | 2 +- src/fix_dt_reset.cpp | 25 +- src/fix_efield.cpp | 16 +- src/fix_enforce2d.cpp | 4 +- src/fix_evaporate.cpp | 27 +- src/fix_external.cpp | 4 +- src/fix_gravity.cpp | 12 +- src/fix_heat.cpp | 18 +- src/fix_indent.cpp | 50 +-- src/fix_langevin.cpp | 48 +- src/fix_lineforce.cpp | 4 +- src/fix_momentum.cpp | 14 +- src/fix_move.cpp | 74 ++-- src/fix_nh.cpp | 163 ++++--- src/fix_nh_sphere.cpp | 4 +- src/fix_nph.cpp | 4 +- src/fix_nph_sphere.cpp | 4 +- src/fix_npt.cpp | 4 +- src/fix_npt_sphere.cpp | 4 +- src/fix_nve.cpp | 2 +- src/fix_nve_limit.cpp | 2 +- src/fix_nve_noforce.cpp | 2 +- src/fix_nve_sphere.cpp | 14 +- src/fix_nvt.cpp | 4 +- src/fix_nvt_sllod.cpp | 10 +- src/fix_nvt_sphere.cpp | 4 +- src/fix_orient_fcc.cpp | 21 +- src/fix_planeforce.cpp | 4 +- src/fix_press_berendsen.cpp | 87 ++-- src/fix_print.cpp | 16 +- src/fix_recenter.cpp | 14 +- src/fix_restrain.cpp | 14 +- src/fix_rigid.cpp | 97 ++-- src/fix_rigid_nvt.cpp | 14 +- src/fix_setforce.cpp | 24 +- src/fix_shake.cpp | 50 +-- src/fix_shear_history.cpp | 4 +- src/fix_spring.cpp | 21 +- src/fix_spring_rg.cpp | 2 +- src/fix_spring_self.cpp | 4 +- src/fix_store_force.cpp | 2 +- src/fix_store_state.cpp | 74 ++-- src/fix_temp_berendsen.cpp | 16 +- src/fix_temp_rescale.cpp | 16 +- src/fix_thermal_conductivity.cpp | 19 +- src/fix_tmd.cpp | 26 +- src/fix_ttm.cpp | 41 +- src/fix_viscosity.cpp | 25 +- src/fix_viscous.cpp | 8 +- src/fix_wall.cpp | 28 +- src/fix_wall_harmonic.cpp | 2 +- src/fix_wall_lj126.cpp | 2 +- src/fix_wall_lj93.cpp | 2 +- src/fix_wall_reflect.cpp | 30 +- src/fix_wall_region.cpp | 16 +- src/force.cpp | 51 +-- src/group.cpp | 53 ++- src/improper.cpp | 4 +- src/input.cpp | 192 ++++---- src/irregular.cpp | 3 - src/kspace.cpp | 14 +- src/lammps.cpp | 78 ++-- src/lattice.cpp | 70 ++- src/memory.cpp | 6 +- src/min.cpp | 21 +- src/min_cg.cpp | 3 - src/min_fire.cpp | 3 - src/min_hftn.cpp | 3 - src/min_linesearch.cpp | 3 - src/min_quickmin.cpp | 3 - src/minimize.cpp | 8 +- src/modify.cpp | 35 +- src/neigh_bond.cpp | 16 +- src/neigh_derive.cpp | 14 +- src/neigh_full.cpp | 10 +- src/neigh_gran.cpp | 10 +- src/neigh_half_bin.cpp | 6 +- src/neigh_half_multi.cpp | 6 +- src/neigh_half_nsq.cpp | 4 +- src/neigh_respa.cpp | 30 +- src/neighbor.cpp | 85 ++-- src/output.cpp | 46 +- src/pair.cpp | 59 ++- src/pair_born.cpp | 13 +- src/pair_buck.cpp | 13 +- src/pair_buck_coul_cut.cpp | 15 +- src/pair_coul_cut.cpp | 11 +- src/pair_coul_debye.cpp | 5 +- src/pair_dpd.cpp | 17 +- src/pair_dpd_tstat.cpp | 11 +- src/pair_gauss.cpp | 11 +- src/pair_hybrid.cpp | 27 +- src/pair_hybrid_overlay.cpp | 9 +- src/pair_lj96_cut.cpp | 11 +- src/pair_lj_cubic.cpp | 9 +- src/pair_lj_cut.cpp | 11 +- src/pair_lj_cut_coul_cut.cpp | 11 +- src/pair_lj_cut_coul_debye.cpp | 2 +- src/pair_lj_expand.cpp | 9 +- src/pair_lj_gromacs.cpp | 13 +- src/pair_lj_gromacs_coul_gromacs.cpp | 15 +- src/pair_lj_smooth.cpp | 13 +- src/pair_morse.cpp | 11 +- src/pair_soft.cpp | 9 +- src/pair_table.cpp | 53 ++- src/pair_yukawa.cpp | 9 +- src/pointers.h | 7 + src/random_mars.cpp | 2 +- src/random_park.cpp | 4 +- src/read_data.cpp | 233 +++++----- src/read_restart.cpp | 40 +- src/region.cpp | 46 +- src/region_block.cpp | 17 +- src/region_cone.cpp | 14 +- src/region_cylinder.cpp | 11 +- src/region_intersect.cpp | 9 +- src/region_plane.cpp | 2 +- src/region_prism.cpp | 29 +- src/region_sphere.cpp | 2 +- src/region_union.cpp | 9 +- src/replicate.cpp | 21 +- src/respa.cpp | 52 +-- src/run.cpp | 43 +- src/set.cpp | 152 +++---- src/special.cpp | 7 +- src/thermo.cpp | 227 +++++----- src/update.cpp | 28 +- src/variable.cpp | 419 +++++++++--------- src/velocity.cpp | 99 ++--- src/verlet.cpp | 2 +- src/write_restart.cpp | 13 +- 468 files changed, 4628 insertions(+), 5204 deletions(-) diff --git a/src/ASPHERE/compute_erotate_asphere.cpp b/src/ASPHERE/compute_erotate_asphere.cpp index 31d500c4a3..80c4083a9f 100644 --- a/src/ASPHERE/compute_erotate_asphere.cpp +++ b/src/ASPHERE/compute_erotate_asphere.cpp @@ -29,7 +29,7 @@ ComputeERotateAsphere:: ComputeERotateAsphere(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute erotate/asphere command"); + if (narg != 3) error->all(FLERR,"Illegal compute erotate/asphere command"); scalar_flag = 1; extscalar = 1; @@ -38,7 +38,7 @@ ComputeERotateAsphere(LAMMPS *lmp, int narg, char **arg) : avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Compute erotate/asphere requires atom style ellipsoid"); + error->all(FLERR,"Compute erotate/asphere requires atom style ellipsoid"); } /* ---------------------------------------------------------------------- */ @@ -55,7 +55,7 @@ void ComputeERotateAsphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) - error->one("Compute erotate/asphere requires extended particles"); + error->one(FLERR,"Compute erotate/asphere requires extended particles"); pfactor = 0.5 * force->mvv2e; } diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp index b4fb8c79f8..69139369cf 100755 --- a/src/ASPHERE/compute_temp_asphere.cpp +++ b/src/ASPHERE/compute_temp_asphere.cpp @@ -41,7 +41,7 @@ enum{ROTATE,ALL}; ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute temp/asphere command"); + if (narg < 3) error->all(FLERR,"Illegal compute temp/asphere command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -56,19 +56,19 @@ ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"bias") == 0) { - if (iarg+2 > narg) error->all("Illegal compute temp/asphere command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/asphere command"); tempbias = 1; int n = strlen(arg[iarg+1]) + 1; id_bias = new char[n]; strcpy(id_bias,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"dof") == 0) { - if (iarg+2 > narg) error->all("Illegal compute temp/asphere command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/asphere command"); if (strcmp(arg[iarg+1],"rotate") == 0) mode = ROTATE; else if (strcmp(arg[iarg+1],"all") == 0) mode = ALL; - else error->all("Illegal compute temp/asphere command"); + else error->all(FLERR,"Illegal compute temp/asphere command"); iarg += 2; - } else error->all("Illegal compute temp/asphere command"); + } else error->all(FLERR,"Illegal compute temp/asphere command"); } vector = new double[6]; @@ -77,7 +77,7 @@ ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) : avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Compute temp/asphere requires atom style ellipsoid"); + error->all(FLERR,"Compute temp/asphere requires atom style ellipsoid"); } /* ---------------------------------------------------------------------- */ @@ -101,18 +101,18 @@ void ComputeTempAsphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) - error->one("Compute temp/asphere requires extended particles"); + error->one(FLERR,"Compute temp/asphere requires extended particles"); if (tempbias) { int i = modify->find_compute(id_bias); - if (i < 0) error->all("Could not find compute ID for temperature bias"); + if (i < 0) error->all(FLERR,"Could not find compute ID for temperature bias"); tbias = modify->compute[i]; if (tbias->tempflag == 0) - error->all("Bias compute does not calculate temperature"); + error->all(FLERR,"Bias compute does not calculate temperature"); if (tbias->tempbias == 0) - error->all("Bias compute does not calculate a velocity bias"); + error->all(FLERR,"Bias compute does not calculate a velocity bias"); if (tbias->igroup != igroup) - error->all("Bias compute group does not match compute group"); + error->all(FLERR,"Bias compute group does not match compute group"); tbias->init(); if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; else tempbias = 1; diff --git a/src/ASPHERE/fix_nh_asphere.cpp b/src/ASPHERE/fix_nh_asphere.cpp index bc58472bb5..3d91262345 100644 --- a/src/ASPHERE/fix_nh_asphere.cpp +++ b/src/ASPHERE/fix_nh_asphere.cpp @@ -35,7 +35,7 @@ FixNHAsphere::FixNHAsphere(LAMMPS *lmp, int narg, char **arg) : { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Compute nvt/nph/npt asphere requires atom style ellipsoid"); + error->all(FLERR,"Compute nvt/nph/npt asphere requires atom style ellipsoid"); } /* ---------------------------------------------------------------------- */ @@ -52,7 +52,7 @@ void FixNHAsphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) - error->one("Fix nvt/nph/npt asphere requires extended particles"); + error->one(FLERR,"Fix nvt/nph/npt asphere requires extended particles"); FixNH::init(); } diff --git a/src/ASPHERE/fix_nph_asphere.cpp b/src/ASPHERE/fix_nph_asphere.cpp index 025137def2..094e0f06a6 100644 --- a/src/ASPHERE/fix_nph_asphere.cpp +++ b/src/ASPHERE/fix_nph_asphere.cpp @@ -24,9 +24,9 @@ FixNPHAsphere::FixNPHAsphere(LAMMPS *lmp, int narg, char **arg) : FixNHAsphere(lmp, narg, arg) { if (tstat_flag) - error->all("Temperature control can not be used with fix nph/asphere"); + error->all(FLERR,"Temperature control can not be used with fix nph/asphere"); if (!pstat_flag) - error->all("Pressure control must be used with fix nph/asphere"); + error->all(FLERR,"Pressure control must be used with fix nph/asphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/ASPHERE/fix_npt_asphere.cpp b/src/ASPHERE/fix_npt_asphere.cpp index 44ed01ea45..2c3c70e948 100755 --- a/src/ASPHERE/fix_npt_asphere.cpp +++ b/src/ASPHERE/fix_npt_asphere.cpp @@ -24,9 +24,9 @@ FixNPTAsphere::FixNPTAsphere(LAMMPS *lmp, int narg, char **arg) : FixNHAsphere(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix npt/asphere"); + error->all(FLERR,"Temperature control must be used with fix npt/asphere"); if (!pstat_flag) - error->all("Pressure control must be used with fix npt/asphere"); + error->all(FLERR,"Pressure control must be used with fix npt/asphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/ASPHERE/fix_nve_asphere.cpp b/src/ASPHERE/fix_nve_asphere.cpp index e078d2fb75..17ae8950e1 100755 --- a/src/ASPHERE/fix_nve_asphere.cpp +++ b/src/ASPHERE/fix_nve_asphere.cpp @@ -38,7 +38,7 @@ FixNVEAsphere::FixNVEAsphere(LAMMPS *lmp, int narg, char **arg) : { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Compute nve/asphere requires atom style ellipsoid"); + error->all(FLERR,"Compute nve/asphere requires atom style ellipsoid"); } /* ---------------------------------------------------------------------- */ @@ -55,7 +55,7 @@ void FixNVEAsphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) - error->one("Fix nve/asphere requires extended particles"); + error->one(FLERR,"Fix nve/asphere requires extended particles"); FixNVE::init(); } diff --git a/src/ASPHERE/fix_nvt_asphere.cpp b/src/ASPHERE/fix_nvt_asphere.cpp index 4137941be9..8578da033e 100755 --- a/src/ASPHERE/fix_nvt_asphere.cpp +++ b/src/ASPHERE/fix_nvt_asphere.cpp @@ -25,9 +25,9 @@ FixNVTAsphere::FixNVTAsphere(LAMMPS *lmp, int narg, char **arg) : FixNHAsphere(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt/asphere"); + error->all(FLERR,"Temperature control must be used with fix nvt/asphere"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt/asphere"); + error->all(FLERR,"Pressure control can not be used with fix nvt/asphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/ASPHERE/pair_gayberne.cpp b/src/ASPHERE/pair_gayberne.cpp index 97a7bc56b3..19dfdecde8 100755 --- a/src/ASPHERE/pair_gayberne.cpp +++ b/src/ASPHERE/pair_gayberne.cpp @@ -31,9 +31,6 @@ #include "memory.h" #include "error.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - using namespace LAMMPS_NS; enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; @@ -43,7 +40,7 @@ enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; PairGayBerne::PairGayBerne(LAMMPS *lmp) : Pair(lmp) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Pair gayberne requires atom style ellipsoid"); + if (!avec) error->all(FLERR,"Pair gayberne requires atom style ellipsoid"); single_enable = 0; } @@ -262,7 +259,7 @@ void PairGayBerne::allocate() void PairGayBerne::settings(int narg, char **arg) { - if (narg != 4) error->all("Illegal pair_style command"); + if (narg != 4) error->all(FLERR,"Illegal pair_style command"); gamma = force->numeric(arg[0]); upsilon = force->numeric(arg[1])/2.0; @@ -286,7 +283,7 @@ void PairGayBerne::settings(int narg, char **arg) void PairGayBerne::coeff(int narg, char **arg) { if (narg < 10 || narg > 11) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -330,7 +327,7 @@ void PairGayBerne::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -348,7 +345,7 @@ void PairGayBerne::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair gayberne requires atoms with same type have same shape"); + error->all(FLERR,"Pair gayberne requires atoms with same type have same shape"); if (shape1[i][0] == 0.0) shape1[i][0] = shape1[i][1] = shape1[i][2] = 1.0; shape2[i][0] = shape1[i][0]*shape1[i][0]; @@ -366,7 +363,7 @@ void PairGayBerne::init_style() double PairGayBerne::init_one(int i, int j) { if (setwell[i] == 0 || setwell[j] == 0) - error->all("Pair gayberne epsilon a,b,c coeffs are not all set"); + error->all(FLERR,"Pair gayberne epsilon a,b,c coeffs are not all set"); if (setflag[i][j] == 0) { epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], @@ -545,7 +542,7 @@ double PairGayBerne::gayberne_analytic(const int i,const int j,double a1[3][3], MathExtra::plus3(g1,g2,g12); double kappa[3]; int ierror = MathExtra::mldivide3(g12,r12,kappa); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); // tempv = G12^-1*r12hat @@ -576,7 +573,7 @@ double PairGayBerne::gayberne_analytic(const int i,const int j,double a1[3][3], double iota[3]; MathExtra::plus3(b1,b2,b12); ierror = MathExtra::mldivide3(b12,r12,iota); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); // tempv = G12^-1*r12hat @@ -726,7 +723,7 @@ double PairGayBerne::gayberne_lj(const int i,const int j,double a1[3][3], g12[1][2] = g1[1][2]; g12[2][1] = g1[2][1]; double kappa[3]; int ierror = MathExtra::mldivide3(g12,r12,kappa); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); // tempv = G12^-1*r12hat @@ -762,7 +759,7 @@ double PairGayBerne::gayberne_lj(const int i,const int j,double a1[3][3], b12[0][2] = b1[0][2]; b12[2][0] = b1[2][0]; b12[1][2] = b1[1][2]; b12[2][1] = b1[2][1]; ierror = MathExtra::mldivide3(b12,r12,iota); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); // tempv = G12^-1*r12hat diff --git a/src/ASPHERE/pair_resquared.cpp b/src/ASPHERE/pair_resquared.cpp index 41d964a4e7..20457226d5 100755 --- a/src/ASPHERE/pair_resquared.cpp +++ b/src/ASPHERE/pair_resquared.cpp @@ -31,9 +31,6 @@ #include "memory.h" #include "error.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - using namespace LAMMPS_NS; enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE}; @@ -45,7 +42,7 @@ PairRESquared::PairRESquared(LAMMPS *lmp) : Pair(lmp), cr60(pow(60.0,1.0/3.0)) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Pair resquared requires atom style ellipsoid"); + if (!avec) error->all(FLERR,"Pair resquared requires atom style ellipsoid"); single_enable = 0; @@ -250,7 +247,7 @@ void PairRESquared::allocate() void PairRESquared::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -271,7 +268,7 @@ void PairRESquared::settings(int narg, char **arg) void PairRESquared::coeff(int narg, char **arg) { if (narg < 10 || narg > 11) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -315,7 +312,7 @@ void PairRESquared::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -331,7 +328,7 @@ void PairRESquared::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair gayberne requires atoms with same type have same shape"); + error->all(FLERR,"Pair gayberne requires atoms with same type have same shape"); if (setwell[i]) { shape2[i][0] = shape1[i][0]*shape1[i][0]; shape2[i][1] = shape1[i][1]*shape1[i][1]; @@ -348,7 +345,7 @@ void PairRESquared::init_style() double PairRESquared::init_one(int i, int j) { if (setwell[i] == 0 || setwell[j] == 0) - error->all("Pair resquared epsilon a,b,c coeffs are not all set"); + error->all(FLERR,"Pair resquared epsilon a,b,c coeffs are not all set"); int ishape = 0; if (shape1[i][0] != 0.0 && shape1[i][1] != 0.0 && shape1[i][2] != 0.0) @@ -381,7 +378,7 @@ double PairRESquared::init_one(int i, int j) sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); cut[i][j] = mix_distance(cut[i][i],cut[j][j]); } else - error->all("Pair resquared epsilon and sigma coeffs are not all set"); + error->all(FLERR,"Pair resquared epsilon and sigma coeffs are not all set"); } epsilon[i][j] = epsilon[j][i]; sigma[i][j] = sigma[j][i]; @@ -612,7 +609,7 @@ double PairRESquared::resquared_analytic(const int i, const int j, double temp[3][3]; MathExtra::plus3(wi.gamma,wj.gamma,temp); int ierror = MathExtra::mldivide3(temp,rhat,s); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); sigma12 = 1.0/sqrt(0.5*MathExtra::dot3(s,rhat)); MathExtra::matvec(wi.A,rhat,z1); @@ -644,7 +641,7 @@ double PairRESquared::resquared_analytic(const int i, const int j, MathExtra::times3(wj.aTe,wj.A,temp2); MathExtra::plus3(temp,temp2,temp); ierror = MathExtra::mldivide3(temp,rhat,w); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); h12 = rnorm-sigma12; eta = lambda/nu; @@ -898,7 +895,7 @@ double PairRESquared::resquared_lj(const int i, const int j, // energy int ierror = MathExtra::mldivide3(gamma,rhat,s); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); sigma12 = 1.0/sqrt(0.5*MathExtra::dot3(s,rhat)); double temp[3][3]; @@ -907,7 +904,7 @@ double PairRESquared::resquared_lj(const int i, const int j, temp[1][1] += 1.0; temp[2][2] += 1.0; ierror = MathExtra::mldivide3(temp,rhat,w); - if (ierror) error->all("Bad matrix inversion in mldivide3"); + if (ierror) error->all(FLERR,"Bad matrix inversion in mldivide3"); h12 = rnorm-sigma12; chi = 2.0*MathExtra::dot3(rhat,w); diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp index ed9f16285c..ca69cca5b2 100644 --- a/src/CLASS2/angle_class2.cpp +++ b/src/CLASS2/angle_class2.cpp @@ -267,7 +267,7 @@ void AngleClass2::allocate() void AngleClass2::coeff(int narg, char **arg) { - if (narg < 2) error->all("Incorrect args for angle coefficients"); + if (narg < 2) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -276,7 +276,7 @@ void AngleClass2::coeff(int narg, char **arg) int count = 0; if (strcmp(arg[1],"bb") == 0) { - if (narg != 5) error->all("Incorrect args for angle coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients"); double bb_k_one = force->numeric(arg[2]); double bb_r1_one = force->numeric(arg[3]); @@ -291,7 +291,7 @@ void AngleClass2::coeff(int narg, char **arg) } } else if (strcmp(arg[1],"ba") == 0) { - if (narg != 6) error->all("Incorrect args for angle coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for angle coefficients"); double ba_k1_one = force->numeric(arg[2]); double ba_k2_one = force->numeric(arg[3]); @@ -308,7 +308,7 @@ void AngleClass2::coeff(int narg, char **arg) } } else { - if (narg != 5) error->all("Incorrect args for angle coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients"); double theta0_one = force->numeric(arg[1]); double k2_one = force->numeric(arg[2]); @@ -327,7 +327,7 @@ void AngleClass2::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); for (int i = ilo; i <= ihi; i++) if (setflag_a[i] == 1 && setflag_bb[i] == 1 && setflag_ba[i] == 1) diff --git a/src/CLASS2/bond_class2.cpp b/src/CLASS2/bond_class2.cpp index 39e797ad9e..f18d687fe7 100644 --- a/src/CLASS2/bond_class2.cpp +++ b/src/CLASS2/bond_class2.cpp @@ -129,7 +129,7 @@ void BondClass2::allocate() void BondClass2::coeff(int narg, char **arg) { - if (narg != 5) error->all("Incorrect args for bond coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -150,7 +150,7 @@ void BondClass2::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp index 695333a565..d6e31696d7 100644 --- a/src/CLASS2/dihedral_class2.cpp +++ b/src/CLASS2/dihedral_class2.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define TOLERANCE 0.05 #define SMALL 0.0000001 @@ -214,7 +211,7 @@ void DihedralClass2::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -629,7 +626,7 @@ void DihedralClass2::allocate() void DihedralClass2::coeff(int narg, char **arg) { - if (narg < 2) error->all("Invalid coeffs for this dihedral style"); + if (narg < 2) error->all(FLERR,"Invalid coeffs for this dihedral style"); if (!allocated) allocate(); int ilo,ihi; @@ -638,7 +635,7 @@ void DihedralClass2::coeff(int narg, char **arg) int count = 0; if (strcmp(arg[1],"mbt") == 0) { - if (narg != 6) error->all("Incorrect args for dihedral coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for dihedral coefficients"); double f1_one = force->numeric(arg[2]); double f2_one = force->numeric(arg[3]); @@ -655,7 +652,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } else if (strcmp(arg[1],"ebt") == 0) { - if (narg != 10) error->all("Incorrect args for dihedral coefficients"); + if (narg != 10) error->all(FLERR,"Incorrect args for dihedral coefficients"); double f1_1_one = force->numeric(arg[2]); double f2_1_one = force->numeric(arg[3]); @@ -680,7 +677,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } else if (strcmp(arg[1],"at") == 0) { - if (narg != 10) error->all("Incorrect args for dihedral coefficients"); + if (narg != 10) error->all(FLERR,"Incorrect args for dihedral coefficients"); double f1_1_one = force->numeric(arg[2]); double f2_1_one = force->numeric(arg[3]); @@ -707,7 +704,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } else if (strcmp(arg[1],"aat") == 0) { - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); double k_one = force->numeric(arg[2]); double theta0_1_one = force->numeric(arg[3]); @@ -724,7 +721,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } else if (strcmp(arg[1],"bb13") == 0) { - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); double k_one = force->numeric(arg[2]); double r10_one = force->numeric(arg[3]); @@ -739,7 +736,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } else { - if (narg != 7) error->all("Incorrect args for dihedral coefficients"); + if (narg != 7) error->all(FLERR,"Incorrect args for dihedral coefficients"); double k1_one = force->numeric(arg[1]); double phi1_one = force->numeric(arg[2]); @@ -762,7 +759,7 @@ void DihedralClass2::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); for (int i = ilo; i <= ihi; i++) if (setflag_d[i] == 1 && setflag_mbt[i] == 1 && setflag_ebt[i] == 1 && diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp index 152c29bfa3..7329870aec 100644 --- a/src/CLASS2/improper_class2.cpp +++ b/src/CLASS2/improper_class2.cpp @@ -162,7 +162,7 @@ void ImproperClass2::compute(int eflag, int vflag) "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -526,7 +526,7 @@ void ImproperClass2::allocate() void ImproperClass2::coeff(int narg, char **arg) { - if (narg < 2) error->all("Incorrect args for improper coefficients"); + if (narg < 2) error->all(FLERR,"Incorrect args for improper coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -535,7 +535,7 @@ void ImproperClass2::coeff(int narg, char **arg) int count = 0; if (strcmp(arg[1],"aa") == 0) { - if (narg != 8) error->all("Incorrect args for improper coefficients"); + if (narg != 8) error->all(FLERR,"Incorrect args for improper coefficients"); double k1_one = force->numeric(arg[2]); double k2_one = force->numeric(arg[3]); @@ -558,7 +558,7 @@ void ImproperClass2::coeff(int narg, char **arg) } } else { - if (narg != 3) error->all("Incorrect args for improper coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for improper coefficients"); double k0_one = force->numeric(arg[1]); double chi0_one = force->numeric(arg[2]); @@ -573,7 +573,7 @@ void ImproperClass2::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for improper coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients"); for (int i = ilo; i <= ihi; i++) if (setflag_i[i] == 1 && setflag_aa[i] == 1) setflag[i] = 1; diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index c77443081f..aba3715cc1 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJClass2::PairLJClass2(LAMMPS *lmp) : Pair(lmp) {} @@ -161,7 +158,7 @@ void PairLJClass2::allocate() void PairLJClass2::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -181,7 +178,7 @@ void PairLJClass2::settings(int narg, char **arg) void PairLJClass2::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -205,7 +202,7 @@ void PairLJClass2::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index c7107077d2..b6dc7d8018 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -25,9 +25,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJClass2CoulCut::PairLJClass2CoulCut(LAMMPS *lmp) : Pair(lmp) {} @@ -187,7 +184,7 @@ void PairLJClass2CoulCut::allocate() void PairLJClass2CoulCut::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -212,7 +209,7 @@ void PairLJClass2CoulCut::settings(int narg, char **arg) void PairLJClass2CoulCut::coeff(int narg, char **arg) { - if (narg < 4 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -239,7 +236,7 @@ void PairLJClass2CoulCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -249,7 +246,7 @@ void PairLJClass2CoulCut::coeff(int narg, char **arg) void PairLJClass2CoulCut::init_style() { if (!atom->q_flag) - error->all("Pair style lj/class2/coul/cut requires atom attribute q"); + error->all(FLERR,"Pair style lj/class2/coul/cut requires atom attribute q"); neighbor->request(this); } diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index 280dacad01..b9423c4728 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -202,7 +199,7 @@ void PairLJClass2CoulLong::allocate() void PairLJClass2CoulLong::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul = cut_lj_global; @@ -224,7 +221,7 @@ void PairLJClass2CoulLong::settings(int narg, char **arg) void PairLJClass2CoulLong::coeff(int narg, char **arg) { - if (narg < 4 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -248,7 +245,7 @@ void PairLJClass2CoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -258,7 +255,7 @@ void PairLJClass2CoulLong::coeff(int narg, char **arg) void PairLJClass2CoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style lj/class2/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/class2/coul/long requires atom attribute q"); neighbor->request(this); @@ -267,7 +264,7 @@ void PairLJClass2CoulLong::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; } diff --git a/src/COLLOID/fix_wall_colloid.cpp b/src/COLLOID/fix_wall_colloid.cpp index 7627fca708..e4267358c8 100644 --- a/src/COLLOID/fix_wall_colloid.cpp +++ b/src/COLLOID/fix_wall_colloid.cpp @@ -36,7 +36,7 @@ FixWallColloid::FixWallColloid(LAMMPS *lmp, int narg, char **arg) : void FixWallColloid::init() { if (!atom->sphere_flag) - error->all("Fix wall/colloid requires atom style sphere"); + error->all(FLERR,"Fix wall/colloid requires atom style sphere"); // insure all particles in group are extended particles @@ -51,7 +51,7 @@ void FixWallColloid::init() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - if (flagall) error->all("Fix wall/colloid requires extended particles"); + if (flagall) error->all(FLERR,"Fix wall/colloid requires extended particles"); FixWall::init(); } @@ -154,5 +154,5 @@ void FixWallColloid::wall_particle(int m, int which, double coord) ewall[m+1] += fwall; } - if (onflag) error->one("Particle on or inside fix wall surface"); + if (onflag) error->one(FLERR,"Particle on or inside fix wall surface"); } diff --git a/src/COLLOID/pair_colloid.cpp b/src/COLLOID/pair_colloid.cpp index db0c612aec..1965e98ac0 100644 --- a/src/COLLOID/pair_colloid.cpp +++ b/src/COLLOID/pair_colloid.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - enum{SMALL_SMALL,SMALL_LARGE,LARGE_LARGE}; /* ---------------------------------------------------------------------- */ @@ -144,7 +141,7 @@ void PairColloid::compute(int eflag, int vflag) evdwl = 2.0/9.0*fR * (1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) * sigma6[itype][jtype]/K[6]) - offset[itype][jtype]; - if (rsq <= K[1]) error->one("Overlapping small/large in pair colloid"); + if (rsq <= K[1]) error->one(FLERR,"Overlapping small/large in pair colloid"); break; case LARGE_LARGE: @@ -182,7 +179,7 @@ void PairColloid::compute(int eflag, int vflag) if (eflag) evdwl += a12[itype][jtype]/6.0 * (2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - offset[itype][jtype]; - if (r <= K[1]) error->one("Overlapping large/large in pair colloid"); + if (r <= K[1]) error->one(FLERR,"Overlapping large/large in pair colloid"); break; } @@ -245,7 +242,7 @@ void PairColloid::allocate() void PairColloid::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -265,7 +262,7 @@ void PairColloid::settings(int narg, char **arg) void PairColloid::coeff(int narg, char **arg) { - if (narg < 6 || narg > 7) error->all("Incorrect args for pair coefficients"); + if (narg < 6 || narg > 7) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -281,7 +278,7 @@ void PairColloid::coeff(int narg, char **arg) if (narg == 7) cut_one = force->numeric(arg[6]); if (d1_one < 0.0 || d2_one < 0.0) - error->all("Invalid d1 or d2 value for pair colloid coeff"); + error->all(FLERR,"Invalid d1 or d2 value for pair colloid coeff"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -289,7 +286,7 @@ void PairColloid::coeff(int narg, char **arg) a12[i][j] = a12_one; sigma[i][j] = sigma_one; if (i == j && d1_one != d2_one) - error->all("Invalid d1 or d2 value for pair colloid coeff"); + error->all(FLERR,"Invalid d1 or d2 value for pair colloid coeff"); d1[i][j] = d1_one; d2[i][j] = d2_one; diameter[i][j] = 0.5*(d1_one+d2_one); @@ -299,7 +296,7 @@ void PairColloid::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp index 4975c4f7e2..5eb072b93e 100644 --- a/src/COLLOID/pair_lubricate.cpp +++ b/src/COLLOID/pair_lubricate.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLubricate::PairLubricate(LAMMPS *lmp) : Pair(lmp) @@ -305,7 +302,7 @@ void PairLubricate::allocate() void PairLubricate::settings(int narg, char **arg) { - if (narg != 9) error->all("Illegal pair_style command"); + if (narg != 9) error->all(FLERR,"Illegal pair_style command"); mu = force->numeric(arg[0]); flag1 = force->inumeric(arg[1]); @@ -319,7 +316,7 @@ void PairLubricate::settings(int narg, char **arg) // initialize Marsaglia RNG with processor-unique seed - if (seed <= 0) error->all("Illegal pair_style command"); + if (seed <= 0) error->all(FLERR,"Illegal pair_style command"); delete random; random = new RanMars(lmp,seed + comm->me); @@ -343,7 +340,7 @@ void PairLubricate::settings(int narg, char **arg) void PairLubricate::coeff(int narg, char **arg) { if (narg != 2 && narg != 4) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); @@ -368,7 +365,7 @@ void PairLubricate::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -378,9 +375,9 @@ void PairLubricate::coeff(int narg, char **arg) void PairLubricate::init_style() { if (!atom->sphere_flag) - error->all("Pair lubricate requires atom style sphere"); + error->all(FLERR,"Pair lubricate requires atom style sphere"); if (comm->ghost_velocity == 0) - error->all("Pair lubricate requires ghost atoms store velocity"); + error->all(FLERR,"Pair lubricate requires ghost atoms store velocity"); neighbor->request(this); @@ -390,9 +387,9 @@ void PairLubricate::init_style() double rad,radtype; for (int i = 1; i <= atom->ntypes; i++) { if (!atom->radius_consistency(i,radtype)) - error->all("Pair lubricate requires monodisperse particles"); + error->all(FLERR,"Pair lubricate requires monodisperse particles"); if (i > 1 && radtype != rad) - error->all("Pair lubricate requires monodisperse particles"); + error->all(FLERR,"Pair lubricate requires monodisperse particles"); rad = radtype; } } diff --git a/src/COLLOID/pair_yukawa_colloid.cpp b/src/COLLOID/pair_yukawa_colloid.cpp index 10ef116386..ca68a56c9c 100644 --- a/src/COLLOID/pair_yukawa_colloid.cpp +++ b/src/COLLOID/pair_yukawa_colloid.cpp @@ -122,7 +122,7 @@ void PairYukawaColloid::compute(int eflag, int vflag) void PairYukawaColloid::init_style() { if (!atom->sphere_flag) - error->all("Pair yukawa/colloid requires atom style sphere"); + error->all(FLERR,"Pair yukawa/colloid requires atom style sphere"); neighbor->request(this); @@ -130,7 +130,7 @@ void PairYukawaColloid::init_style() for (int i = 1; i <= atom->ntypes; i++) if (!atom->radius_consistency(i,rad[i])) - error->all("Pair yukawa/colloid requires atoms with same type " + error->all(FLERR,"Pair yukawa/colloid requires atoms with same type " "have same radius"); } diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp index cde9b0c806..64ec41d589 100644 --- a/src/DIPOLE/atom_vec_dipole.cpp +++ b/src/DIPOLE/atom_vec_dipole.cpp @@ -60,7 +60,7 @@ void AtomVecDipole::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -762,11 +762,11 @@ void AtomVecDipole::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[2]); diff --git a/src/DIPOLE/pair_dipole_cut.cpp b/src/DIPOLE/pair_dipole_cut.cpp index 3f9e79332e..f443854b90 100644 --- a/src/DIPOLE/pair_dipole_cut.cpp +++ b/src/DIPOLE/pair_dipole_cut.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairDipoleCut::PairDipoleCut(LAMMPS *lmp) : Pair(lmp) @@ -294,7 +291,7 @@ void PairDipoleCut::allocate() void PairDipoleCut::settings(int narg, char **arg) { if (narg < 1 || narg > 2) - error->all("Incorrect args in pair_style command"); + error->all(FLERR,"Incorrect args in pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -320,7 +317,7 @@ void PairDipoleCut::settings(int narg, char **arg) void PairDipoleCut::coeff(int narg, char **arg) { if (narg < 4 || narg > 6) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -347,7 +344,7 @@ void PairDipoleCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -357,7 +354,7 @@ void PairDipoleCut::coeff(int narg, char **arg) void PairDipoleCut::init_style() { if (!atom->q_flag || !atom->mu_flag || !atom->torque_flag) - error->all("Pair dipole/cut requires atom attributes q, mu, torque"); + error->all(FLERR,"Pair dipole/cut requires atom attributes q, mu, torque"); neighbor->request(this); } diff --git a/src/GPU/fix_gpu.cpp b/src/GPU/fix_gpu.cpp index cdcaaa8458..a444986701 100644 --- a/src/GPU/fix_gpu.cpp +++ b/src/GPU/fix_gpu.cpp @@ -43,10 +43,10 @@ extern double lmp_gpu_forces(double **f, double **tor, double *eatom, FixGPU::FixGPU(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (lmp->cuda) error->all("Cannot use fix GPU with USER-CUDA mode enabled"); + if (lmp->cuda) error->all(FLERR,"Cannot use fix GPU with USER-CUDA mode enabled"); - if (narg < 7) error->all("Illegal fix GPU command"); - if (strcmp(arg[1],"all") != 0) error->all("Illegal fix GPU command"); + if (narg < 7) error->all(FLERR,"Illegal fix GPU command"); + if (strcmp(arg[1],"all") != 0) error->all(FLERR,"Illegal fix GPU command"); int first_gpu, last_gpu; @@ -55,16 +55,16 @@ FixGPU::FixGPU(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[3],"force/neigh") == 0) { _gpu_mode = GPU_NEIGH; if (domain->triclinic) - error->all("Cannot use force/neigh with triclinic box"); + error->all(FLERR,"Cannot use force/neigh with triclinic box"); } else - error->all("Illegal fix GPU command"); + error->all(FLERR,"Illegal fix GPU command"); first_gpu = atoi(arg[4]); last_gpu = atoi(arg[5]); _particle_split = force->numeric(arg[6]); if (_particle_split==0 || _particle_split>1) - error->all("Illegal fix GPU command"); + error->all(FLERR,"Illegal fix GPU command"); int nthreads = 1; int threads_per_atom = -1; @@ -74,16 +74,16 @@ FixGPU::FixGPU(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[7],"nthreads") == 0) nthreads = atoi(arg[8]); else - error->all("Illegal fix GPU command"); + error->all(FLERR,"Illegal fix GPU command"); } else if (narg != 7) - error->all("Illegal fix GPU command"); + error->all(FLERR,"Illegal fix GPU command"); if (nthreads < 1) - error->all("Illegal fix GPU command"); + error->all(FLERR,"Illegal fix GPU command"); #ifndef _OPENMP if (nthreads > 1) - error->all("No OpenMP support compiled in"); + error->all(FLERR,"No OpenMP support compiled in"); #endif int gpu_flag = lmp_init_device(universe->uworld, world, first_gpu, last_gpu, @@ -115,16 +115,16 @@ void FixGPU::init() { // Can only have 1 gpu fix that must be the first fix for a run if ((void*)modify->fix[0] != (void*)this) - error->all("GPU is not the first fix for this run"); + error->all(FLERR,"GPU is not the first fix for this run"); // Hybrid cannot be used with force/neigh option if (_gpu_mode == GPU_NEIGH) if (force->pair_match("hybrid",1) != NULL || force->pair_match("hybrid/overlay",1) != NULL) - error->all("Cannot use pair hybrid with GPU neighbor builds"); + error->all(FLERR,"Cannot use pair hybrid with GPU neighbor builds"); if (_particle_split < 0) if (force->pair_match("hybrid",1) != NULL || force->pair_match("hybrid/overlay",1) != NULL) - error->all("Fix GPU split must be positive for hybrid pair styles"); + error->all(FLERR,"Fix GPU split must be positive for hybrid pair styles"); } /* ---------------------------------------------------------------------- */ diff --git a/src/GPU/gpu_extra.h b/src/GPU/gpu_extra.h index 9fa2d83a12..d9bbb7eaa6 100644 --- a/src/GPU/gpu_extra.h +++ b/src/GPU/gpu_extra.h @@ -28,17 +28,19 @@ namespace GPU_EXTRA { MPI_Allreduce(&error_flag, &all_success, 1, MPI_INT, MPI_MIN, world); if (all_success != 0) { if (all_success == -1) - error->all("Accelerated style in input script but no fix gpu"); + error->all(FLERR,"Accelerated style in input script but no fix gpu"); else if (all_success == -2) - error->all("Could not find/initialize a specified accelerator device"); + error->all(FLERR, + "Could not find/initialize a specified accelerator device"); else if (all_success == -3) - error->all("Insufficient memory on accelerator"); + error->all(FLERR,"Insufficient memory on accelerator"); else if (all_success == -4) - error->all("GPU library not compiled for this accelerator"); + error->all(FLERR,"GPU library not compiled for this accelerator"); else if (all_success == -5) - error->all("Double precision is not supported on this accelerator"); + error->all(FLERR, + "Double precision is not supported on this accelerator"); else - error->all("Unknown error in GPU library"); + error->all(FLERR,"Unknown error in GPU library"); } } diff --git a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp index d19b2d6512..27aedd4192 100644 --- a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp +++ b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp @@ -37,9 +37,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -126,7 +123,7 @@ void PairCGCMMCoulLongGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style cg/cmm/coul/long/gpu requires atom attribute q"); + error->all(FLERR,"Pair style cg/cmm/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with cg/cmm/coul/long/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with cg/cmm/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; @@ -168,7 +165,7 @@ void PairCGCMMCoulLongGPU::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/GPU/pair_cg_cmm_coul_msm.cpp b/src/GPU/pair_cg_cmm_coul_msm.cpp index d1e9b22775..5321945eb2 100644 --- a/src/GPU/pair_cg_cmm_coul_msm.cpp +++ b/src/GPU/pair_cg_cmm_coul_msm.cpp @@ -16,19 +16,17 @@ Contributing author: Mike Brown ------------------------------------------------------------------------- */ +#include "string.h" #include "pair_cg_cmm_coul_msm.h" #include "memory.h" #include "atom.h" #include "force.h" #include "kspace.h" -#include "string.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -enum {C3=0,C4=1}; - using namespace LAMMPS_NS; +enum {C3=0,C4=1}; + /* ---------------------------------------------------------------------- */ PairCGCMMCoulMSM::PairCGCMMCoulMSM(LAMMPS *lmp) : PairCMMCommon(lmp) @@ -73,13 +71,13 @@ void PairCGCMMCoulMSM::settings(int narg, char **arg) { // strip off smoothing type and send args to parent - if (narg < 1) error->all("Illegal pair_style command"); + if (narg < 1) error->all(FLERR,"Illegal pair_style command"); if (strcmp(arg[0],"C3") == 0) _smooth = C3; else if (strcmp(arg[0],"C4") == 0) _smooth = C4; - else error->all("Illegal pair_style command"); + else error->all(FLERR,"Illegal pair_style command"); PairCMMCommon::settings(narg-1,&arg[1]); } @@ -89,7 +87,7 @@ void PairCGCMMCoulMSM::settings(int narg, char **arg) void PairCGCMMCoulMSM::init_style() { if (!atom->q_flag) - error->all("Pair style cg/cut/coul/msm requires atom attribute q"); + error->all(FLERR,"Pair style cg/cut/coul/msm requires atom attribute q"); PairCMMCommon::init_style(); _ia=-1.0/cut_coul_global; diff --git a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp b/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp index d946b739d5..0d079304f1 100644 --- a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp +++ b/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp @@ -36,10 +36,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -enum {C3=0,C4=1}; - // External functions from cuda library for atom decomposition int cmmm_gpu_init(const int ntypes, double **cutsq, int **cg_type, @@ -69,6 +65,8 @@ double cmmm_gpu_bytes(); using namespace LAMMPS_NS; +enum {C3=0,C4=1}; + /* ---------------------------------------------------------------------- */ PairCGCMMCoulMSMGPU::PairCGCMMCoulMSMGPU(LAMMPS *lmp) : PairCGCMMCoulMSM(lmp), @@ -119,7 +117,7 @@ void PairCGCMMCoulMSMGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with cg/cmm/coul/msm/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with cg/cmm/coul/msm/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_cg_cmm_gpu.cpp b/src/GPU/pair_cg_cmm_gpu.cpp index 4ccea32421..b7f7ccd330 100644 --- a/src/GPU/pair_cg_cmm_gpu.cpp +++ b/src/GPU/pair_cg_cmm_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int cmm_gpu_init(const int ntypes, double **cutsq, int **cg_types, @@ -111,7 +108,7 @@ void PairCGCMMGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with GPU CGCMM pair style"); + error->all(FLERR,"Cannot use newton pair with GPU CGCMM pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_coul_long_gpu.cpp b/src/GPU/pair_coul_long_gpu.cpp index 468821dcec..8502e8ae53 100644 --- a/src/GPU/pair_coul_long_gpu.cpp +++ b/src/GPU/pair_coul_long_gpu.cpp @@ -37,9 +37,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -123,7 +120,7 @@ void PairCoulLongGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style coul/long/gpu requires atom attribute q"); + error->all(FLERR,"Pair style coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with coul/long/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double cell_size = sqrt(cut_coul) + neighbor->skin; @@ -153,7 +150,7 @@ void PairCoulLongGPU::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/GPU/pair_gayberne_gpu.cpp b/src/GPU/pair_gayberne_gpu.cpp index c137f0f67c..eb9fd0094c 100644 --- a/src/GPU/pair_gayberne_gpu.cpp +++ b/src/GPU/pair_gayberne_gpu.cpp @@ -38,9 +38,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int gb_gpu_init(const int ntypes, const double gamma, const double upsilon, @@ -77,7 +74,7 @@ PairGayBerneGPU::PairGayBerneGPU(LAMMPS *lmp) : PairGayBerne(lmp), { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Pair gayberne requires atom style ellipsoid"); + error->all(FLERR,"Pair gayberne requires atom style ellipsoid"); quat_nmax = 0; quat = NULL; } @@ -140,7 +137,7 @@ void PairGayBerneGPU::compute(int eflag, int vflag) cpu_time, success, quat); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_start < inum) { cpu_time = MPI_Wtime(); @@ -156,9 +153,9 @@ void PairGayBerneGPU::compute(int eflag, int vflag) void PairGayBerneGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with gayberne/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with gayberne/gpu pair style"); if (!atom->ellipsoid_flag) - error->all("Pair gayberne/gpu requires atom style ellipsoid"); + error->all(FLERR,"Pair gayberne/gpu requires atom style ellipsoid"); // per-type shape precalculations // require that atom shapes are identical within each type @@ -166,7 +163,7 @@ void PairGayBerneGPU::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair gayberne/gpu requires atoms with same type have same shape"); + error->all(FLERR,"Pair gayberne/gpu requires atoms with same type have same shape"); if (shape1[i][0] == 0.0) shape1[i][0] = shape1[i][1] = shape1[i][2] = 1.0; shape2[i][0] = shape1[i][0]*shape1[i][0]; diff --git a/src/GPU/pair_lj96_cut_gpu.cpp b/src/GPU/pair_lj96_cut_gpu.cpp index ce51b12a7b..f09e4636f9 100644 --- a/src/GPU/pair_lj96_cut_gpu.cpp +++ b/src/GPU/pair_lj96_cut_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int lj96_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -110,7 +107,7 @@ void PairLJ96CutGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with lj96/cut/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj96/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp index fa48db0d9a..a1a30bfb17 100644 --- a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp @@ -37,9 +37,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -129,7 +126,7 @@ void PairLJCharmmCoulLongGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style lj/charmm/coul/long/gpu requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with lj/charmm/coul/long/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/charmm/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double cut; @@ -173,7 +170,7 @@ void PairLJCharmmCoulLongGPU::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/GPU/pair_lj_class2_coul_long_gpu.cpp b/src/GPU/pair_lj_class2_coul_long_gpu.cpp index 2c7ea41531..568cec2bf8 100644 --- a/src/GPU/pair_lj_class2_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_class2_coul_long_gpu.cpp @@ -37,9 +37,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -126,7 +123,7 @@ void PairLJClass2CoulLongGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style lj/class2/coul/long/gpu requires atom attribute q"); + error->all(FLERR,"Pair style lj/class2/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with lj/class2/coul/long/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/class2/coul/long/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; @@ -168,7 +165,7 @@ void PairLJClass2CoulLongGPU::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; int maxspecial=0; diff --git a/src/GPU/pair_lj_class2_gpu.cpp b/src/GPU/pair_lj_class2_gpu.cpp index c45fb5bfdb..349c043cde 100644 --- a/src/GPU/pair_lj_class2_gpu.cpp +++ b/src/GPU/pair_lj_class2_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int lj96_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -109,7 +106,7 @@ void PairLJClass2GPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with lj/class2/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/class2/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp index cd19e81ca2..66dbbed46c 100644 --- a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int ljc_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -117,7 +114,7 @@ void PairLJCutCoulCutGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style lj/cut/coul/cut/gpu requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/cut/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with lj/cut/coul/cut/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/cut/coul/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_coul_long_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_gpu.cpp index 2b3a915f0e..80c7926272 100644 --- a/src/GPU/pair_lj_cut_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_long_gpu.cpp @@ -37,9 +37,6 @@ #include "kspace.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -127,7 +124,7 @@ void PairLJCutCoulLongGPU::compute(int eflag, int vflag) atom->nlocal, domain->boxlo, domain->prd); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startq_flag) - error->all("Pair style lj/cut/coul/long/gpu requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long/gpu requires atom attribute q"); if (force->newton_pair) - error->all("Cannot use newton pair with lj/cut/could/cut/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/cut/could/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; @@ -171,7 +168,7 @@ void PairLJCutCoulLongGPU::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/GPU/pair_lj_cut_gpu.cpp b/src/GPU/pair_lj_cut_gpu.cpp index 63a908d3e7..198328274e 100644 --- a/src/GPU/pair_lj_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int ljl_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -110,7 +107,7 @@ void PairLJCutGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with lj/cut/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/cut/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_cut_tgpu.cpp b/src/GPU/pair_lj_cut_tgpu.cpp index 043cf0e5bb..7b9aa9af0b 100644 --- a/src/GPU/pair_lj_cut_tgpu.cpp +++ b/src/GPU/pair_lj_cut_tgpu.cpp @@ -35,9 +35,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int ljl_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -115,7 +112,7 @@ void PairLJCutTGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with lj/cut/tgpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/cut/tgpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_lj_expand_gpu.cpp b/src/GPU/pair_lj_expand_gpu.cpp index f45429a9db..b610e02bc3 100644 --- a/src/GPU/pair_lj_expand_gpu.cpp +++ b/src/GPU/pair_lj_expand_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int lje_gpu_init(const int ntypes, double **cutsq, double **host_lj1, @@ -111,7 +108,7 @@ void PairLJExpandGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with lj/expand/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with lj/expand/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_morse_gpu.cpp b/src/GPU/pair_morse_gpu.cpp index ae5fcdfe64..8ede76217b 100644 --- a/src/GPU/pair_morse_gpu.cpp +++ b/src/GPU/pair_morse_gpu.cpp @@ -36,9 +36,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int mor_gpu_init(const int ntypes, double **cutsq, double **host_morse1, @@ -109,7 +106,7 @@ void PairMorseGPU::compute(int eflag, int vflag) vflag_atom, host_start, cpu_time, success); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_startnewton_pair) - error->all("Cannot use newton pair with morse/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with morse/gpu pair style"); // Repeat cutsq calculation because done after call to init_style double maxcut = -1.0; diff --git a/src/GPU/pair_resquared_gpu.cpp b/src/GPU/pair_resquared_gpu.cpp index 69b6060394..f50d1feda6 100644 --- a/src/GPU/pair_resquared_gpu.cpp +++ b/src/GPU/pair_resquared_gpu.cpp @@ -38,9 +38,6 @@ #include "string.h" #include "gpu_extra.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition int re_gpu_init(const int ntypes, double **shape, double **well, @@ -76,7 +73,7 @@ PairRESquaredGPU::PairRESquaredGPU(LAMMPS *lmp) : PairRESquared(lmp), { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Pair gayberne requires atom style ellipsoid"); + error->all(FLERR,"Pair gayberne requires atom style ellipsoid"); quat_nmax = 0; quat = NULL; } @@ -139,7 +136,7 @@ void PairRESquaredGPU::compute(int eflag, int vflag) cpu_time, success, quat); } if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (host_start < inum) { cpu_time = MPI_Wtime(); @@ -155,9 +152,9 @@ void PairRESquaredGPU::compute(int eflag, int vflag) void PairRESquaredGPU::init_style() { if (force->newton_pair) - error->all("Cannot use newton pair with resquared/gpu pair style"); + error->all(FLERR,"Cannot use newton pair with resquared/gpu pair style"); if (!atom->ellipsoid_flag) - error->all("Pair resquared/gpu requires atom style ellipsoid"); + error->all(FLERR,"Pair resquared/gpu requires atom style ellipsoid"); // per-type shape precalculations // require that atom shapes are identical within each type @@ -165,7 +162,7 @@ void PairRESquaredGPU::init_style() for (int i = 1; i <= atom->ntypes; i++) { if (!atom->shape_consistency(i,shape1[i][0],shape1[i][1],shape1[i][2])) - error->all("Pair resquared/gpu requires atoms with same type have same shape"); + error->all(FLERR,"Pair resquared/gpu requires atoms with same type have same shape"); if (setwell[i]) { shape2[i][0] = shape1[i][0]*shape1[i][0]; shape2[i][1] = shape1[i][1]*shape1[i][1]; diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp index f9a929a30a..044d018c28 100644 --- a/src/GPU/pppm_gpu.cpp +++ b/src/GPU/pppm_gpu.cpp @@ -52,9 +52,6 @@ using namespace LAMMPS_NS; #define ONEF 1.0 #endif -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - // External functions from cuda library for atom decomposition #ifdef FFT_SINGLE @@ -82,7 +79,7 @@ double PPPM_GPU_API(bytes)(); PPPMGPU::PPPMGPU(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg) { - if (narg != 1) error->all("Illegal kspace_style pppm/gpu command"); + if (narg != 1) error->all(FLERR,"Illegal kspace_style pppm/gpu command"); density_brick_gpu = vd_brick = NULL; } @@ -106,7 +103,7 @@ void PPPMGPU::init() // GPU precision specific init. if (order>8) - error->all("Cannot use order greater than 8 with pppm/gpu."); + error->all(FLERR,"Cannot use order greater than 8 with pppm/gpu."); PPPM_GPU_API(clear)(poisson_time); int success; @@ -140,9 +137,9 @@ void PPPMGPU::compute(int eflag, int vflag) atom->q, domain->boxlo, delxinv, delyinv, delzinv); if (!success) - error->one("Out of memory on GPGPU"); + error->one(FLERR,"Out of memory on GPGPU"); if (flag != 0) - error->one("Out of range atoms - cannot compute PPPM"); + error->one(FLERR,"Out of range atoms - cannot compute PPPM"); int i; diff --git a/src/GRANULAR/fix_freeze.cpp b/src/GRANULAR/fix_freeze.cpp index 997337a67b..848574e5fe 100644 --- a/src/GRANULAR/fix_freeze.cpp +++ b/src/GRANULAR/fix_freeze.cpp @@ -27,10 +27,10 @@ using namespace LAMMPS_NS; FixFreeze::FixFreeze(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix freeze command"); + if (narg != 3) error->all(FLERR,"Illegal fix freeze command"); if (!atom->torque_flag) - error->all("Fix freeze requires atom attribute torque"); + error->all(FLERR,"Fix freeze requires atom attribute torque"); vector_flag = 1; size_vector = 3; @@ -61,7 +61,7 @@ void FixFreeze::init() int count = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"freeze") == 0) count++; - if (count > 1) error->all("More than one fix freeze"); + if (count > 1) error->all(FLERR,"More than one fix freeze"); } /* ---------------------------------------------------------------------- */ diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp index 1248c05db0..4dcf9fc3bc 100644 --- a/src/GRANULAR/fix_pour.cpp +++ b/src/GRANULAR/fix_pour.cpp @@ -39,12 +39,12 @@ using namespace LAMMPS_NS; FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix pour command"); + if (narg < 6) error->all(FLERR,"Illegal fix pour command"); time_depend = 1; if (!atom->radius_flag || !atom->rmass_flag) - error->all("Fix pour requires atom attributes radius, rmass"); + error->all(FLERR,"Fix pour requires atom attributes radius, rmass"); // required args @@ -52,7 +52,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : ntype = atoi(arg[4]); seed = atoi(arg[5]); - if (seed <= 0) error->all("Illegal fix pour command"); + if (seed <= 0) error->all(FLERR,"Illegal fix pour command"); PI = 4.0*atan(1.0); @@ -71,32 +71,32 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix pour command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix pour command"); iregion = domain->find_region(arg[iarg+1]); - if (iregion == -1) error->all("Fix pour region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Fix pour region ID does not exist"); iarg += 2; } else if (strcmp(arg[iarg],"diam") == 0) { - if (iarg+3 > narg) error->all("Illegal fix pour command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix pour command"); radius_lo = 0.5 * atof(arg[iarg+1]); radius_hi = 0.5 * atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"dens") == 0) { - if (iarg+3 > narg) error->all("Illegal fix pour command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix pour command"); density_lo = atof(arg[iarg+1]); density_hi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"vol") == 0) { - if (iarg+3 > narg) error->all("Illegal fix pour command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix pour command"); volfrac = atof(arg[iarg+1]); maxattempt = atoi(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"rate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix pour command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix pour command"); rate = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"vel") == 0) { if (domain->dimension == 3) { - if (iarg+6 > narg) error->all("Illegal fix pour command"); + if (iarg+6 > narg) error->all(FLERR,"Illegal fix pour command"); vxlo = atof(arg[iarg+1]); vxhi = atof(arg[iarg+2]); vylo = atof(arg[iarg+3]); @@ -104,23 +104,23 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : vz = atof(arg[iarg+5]); iarg += 6; } else { - if (iarg+4 > narg) error->all("Illegal fix pour command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix pour command"); vxlo = atof(arg[iarg+1]); vxhi = atof(arg[iarg+2]); vy = atof(arg[iarg+3]); vz = 0.0; iarg += 4; } - } else error->all("Illegal fix pour command"); + } else error->all(FLERR,"Illegal fix pour command"); } // error checks on region and its extent being inside simulation box - if (iregion == -1) error->all("Must specify a region in fix pour"); + if (iregion == -1) error->all(FLERR,"Must specify a region in fix pour"); if (domain->regions[iregion]->bboxflag == 0) - error->all("Fix pour region does not support a bounding box"); + error->all(FLERR,"Fix pour region does not support a bounding box"); if (domain->regions[iregion]->dynamic_check()) - error->all("Fix pour region cannot be dynamic"); + error->all(FLERR,"Fix pour region cannot be dynamic"); if (strcmp(domain->regions[iregion]->style,"block") == 0) { region_style = 1; @@ -133,7 +133,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : if (xlo < domain->boxlo[0] || xhi > domain->boxhi[0] || ylo < domain->boxlo[1] || yhi > domain->boxhi[1] || zlo < domain->boxlo[2] || zhi > domain->boxhi[2]) - error->all("Insertion region extends outside simulation box"); + error->all(FLERR,"Insertion region extends outside simulation box"); } else if (strcmp(domain->regions[iregion]->style,"cylinder") == 0) { region_style = 2; char axis = ((RegCylinder *) domain->regions[iregion])->axis; @@ -143,15 +143,15 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : zlo = ((RegCylinder *) domain->regions[iregion])->lo; zhi = ((RegCylinder *) domain->regions[iregion])->hi; if (axis != 'z') - error->all("Must use a z-axis cylinder with fix pour"); + error->all(FLERR,"Must use a z-axis cylinder with fix pour"); if (xc-rc < domain->boxlo[0] || xc+rc > domain->boxhi[0] || yc-rc < domain->boxlo[1] || yc+rc > domain->boxhi[1] || zlo < domain->boxlo[2] || zhi > domain->boxhi[2]) - error->all("Insertion region extends outside simulation box"); - } else error->all("Must use a block or cylinder region with fix pour"); + error->all(FLERR,"Insertion region extends outside simulation box"); + } else error->all(FLERR,"Must use a block or cylinder region with fix pour"); if (region_style == 2 && domain->dimension == 2) - error->all("Must use a block region with fix pour for 2d simulations"); + error->all(FLERR,"Must use a block region with fix pour for 2d simulations"); // random number generator, same for all procs @@ -171,7 +171,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : for (ifix = 0; ifix < modify->nfix; ifix++) if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break; if (ifix == modify->nfix) - error->all("No fix gravity defined for fix pour"); + error->all(FLERR,"No fix gravity defined for fix pour"); grav = - ((FixGravity *) modify->fix[ifix])->magnitude * force->ftm2v; // nfreq = timesteps between insertions @@ -260,7 +260,7 @@ int FixPour::setmask() void FixPour::init() { - if (domain->triclinic) error->all("Cannot use fix pour with triclinic box"); + if (domain->triclinic) error->all(FLERR,"Cannot use fix pour with triclinic box"); // insure gravity fix exists // for 3d must point in -z, for 2d must point in -y @@ -270,7 +270,7 @@ void FixPour::init() for (ifix = 0; ifix < modify->nfix; ifix++) if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break; if (ifix == modify->nfix) - error->all("No fix gravity defined for fix pour"); + error->all(FLERR,"No fix gravity defined for fix pour"); double xgrav = ((FixGravity *) modify->fix[ifix])->xgrav; double ygrav = ((FixGravity *) modify->fix[ifix])->ygrav; @@ -279,16 +279,16 @@ void FixPour::init() if (domain->dimension == 3) { if (fabs(xgrav) > EPSILON || fabs(ygrav) > EPSILON || fabs(zgrav+1.0) > EPSILON) - error->all("Gravity must point in -z to use with fix pour in 3d"); + error->all(FLERR,"Gravity must point in -z to use with fix pour in 3d"); } else { if (fabs(xgrav) > EPSILON || fabs(ygrav+1.0) > EPSILON || fabs(zgrav) > EPSILON) - error->all("Gravity must point in -y to use with fix pour in 2d"); + error->all(FLERR,"Gravity must point in -y to use with fix pour in 2d"); } double gnew = - ((FixGravity *) modify->fix[ifix])->magnitude * force->ftm2v; if (gnew != grav) - error->all("Gravity changed since fix pour was created"); + error->all(FLERR,"Gravity changed since fix pour was created"); } /* ---------------------------------------------------------------------- @@ -415,7 +415,7 @@ void FixPour::pre_exchange() ninserted += nnear-nprevious; if (nnear - nprevious < nnew && me == 0) - error->warning("Less insertions than requested",0); + error->warning(FLERR,"Less insertions than requested",0); // check if new atom is in my sub-box or above it if I'm highest proc // if so, add to my list via create_atom() @@ -573,5 +573,5 @@ void FixPour::xyz_random(double h, double *coord) void FixPour::reset_dt() { - error->all("Cannot change timestep with fix pour"); + error->all(FLERR,"Cannot change timestep with fix pour"); } diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 9758283399..a23f70c44d 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -36,18 +36,15 @@ enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY}; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 10) error->all("Illegal fix wall/gran command"); + if (narg < 10) error->all(FLERR,"Illegal fix wall/gran command"); if (!atom->sphere_flag) - error->all("Fix wall/gran requires atom style sphere"); + error->all(FLERR,"Fix wall/gran requires atom style sphere"); restart_peratom = 1; create_attribute = 1; @@ -69,7 +66,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 || xmu < 0.0 || xmu > 1.0 || dampflag < 0 || dampflag > 1) - error->all("Illegal fix wall/gran command"); + error->all(FLERR,"Illegal fix wall/gran command"); // convert Kn and Kt from pressure units to force/distance^2 if Hertzian @@ -82,7 +79,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : int iarg = 9; if (strcmp(arg[iarg],"xplane") == 0) { - if (narg < iarg+3) error->all("Illegal fix wall/gran command"); + if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = XPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = atof(arg[iarg+1]); @@ -90,7 +87,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : else hi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"yplane") == 0) { - if (narg < iarg+3) error->all("Illegal fix wall/gran command"); + if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = YPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = atof(arg[iarg+1]); @@ -98,7 +95,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : else hi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"zplane") == 0) { - if (narg < iarg+3) error->all("Illegal fix wall/gran command"); + if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = ZPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = atof(arg[iarg+1]); @@ -106,7 +103,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : else hi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"zcylinder") == 0) { - if (narg < iarg+2) error->all("Illegal fix wall/gran command"); + if (narg < iarg+2) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = ZCYLINDER; lo = hi = 0.0; cylradius = atof(arg[iarg+1]); @@ -120,45 +117,45 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"wiggle") == 0) { - if (iarg+4 > narg) error->all("Illegal fix wall/gran command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix wall/gran command"); if (strcmp(arg[iarg+1],"x") == 0) axis = 0; else if (strcmp(arg[iarg+1],"y") == 0) axis = 1; else if (strcmp(arg[iarg+1],"z") == 0) axis = 2; - else error->all("Illegal fix wall/gran command"); + else error->all(FLERR,"Illegal fix wall/gran command"); amplitude = atof(arg[iarg+2]); period = atof(arg[iarg+3]); wiggle = 1; iarg += 4; } else if (strcmp(arg[iarg],"shear") == 0) { - if (iarg+3 > narg) error->all("Illegal fix wall/gran command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix wall/gran command"); if (strcmp(arg[iarg+1],"x") == 0) axis = 0; else if (strcmp(arg[iarg+1],"y") == 0) axis = 1; else if (strcmp(arg[iarg+1],"z") == 0) axis = 2; - else error->all("Illegal fix wall/gran command"); + else error->all(FLERR,"Illegal fix wall/gran command"); vshear = atof(arg[iarg+2]); wshear = 1; iarg += 3; - } else error->all("Illegal fix wall/gran command"); + } else error->all(FLERR,"Illegal fix wall/gran command"); } if (wallstyle == XPLANE && domain->xperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == YPLANE && domain->yperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == ZPLANE && domain->zperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == ZCYLINDER && (domain->xperiodic || domain->yperiodic)) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); - if (wiggle && wshear) error->all("Cannot wiggle and shear fix wall/gran"); + if (wiggle && wshear) error->all(FLERR,"Cannot wiggle and shear fix wall/gran"); if (wiggle && wallstyle == ZCYLINDER && axis != 2) - error->all("Invalid wiggle direction for fix wall/gran"); + error->all(FLERR,"Invalid wiggle direction for fix wall/gran"); if (wshear && wallstyle == XPLANE && axis == 0) - error->all("Invalid shear direction for fix wall/gran"); + error->all(FLERR,"Invalid shear direction for fix wall/gran"); if (wshear && wallstyle == YPLANE && axis == 1) - error->all("Invalid shear direction for fix wall/gran"); + error->all(FLERR,"Invalid shear direction for fix wall/gran"); if (wshear && wallstyle == ZPLANE && axis == 2) - error->all("Invalid shear direction for fix wall/gran"); + error->all(FLERR,"Invalid shear direction for fix wall/gran"); // setup oscillations @@ -226,7 +223,7 @@ void FixWallGran::init() pairstyle = HOOKE_HISTORY; else if (force->pair_match("gran/hertz/history",1)) pairstyle = HERTZ_HISTORY; - else error->all("Fix wall/gran is incompatible with Pair style"); + else error->all(FLERR,"Fix wall/gran is incompatible with Pair style"); } /* ---------------------------------------------------------------------- */ diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp index 6c193e3517..a418e9352d 100644 --- a/src/GRANULAR/pair_gran_hertz_history.cpp +++ b/src/GRANULAR/pair_gran_hertz_history.cpp @@ -28,9 +28,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairGranHertzHistory::PairGranHertzHistory(LAMMPS *lmp) : @@ -256,7 +253,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag) void PairGranHertzHistory::settings(int narg, char **arg) { - if (narg != 6) error->all("Illegal pair_style command"); + if (narg != 6) error->all(FLERR,"Illegal pair_style command"); kn = force->numeric(arg[0]); if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0; @@ -272,7 +269,7 @@ void PairGranHertzHistory::settings(int narg, char **arg) if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 || xmu < 0.0 || xmu > 1.0 || dampflag < 0 || dampflag > 1) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); // convert Kn and Kt from pressure units to force/distance^2 diff --git a/src/GRANULAR/pair_gran_hooke.cpp b/src/GRANULAR/pair_gran_hooke.cpp index 542bbaa582..95651e7606 100644 --- a/src/GRANULAR/pair_gran_hooke.cpp +++ b/src/GRANULAR/pair_gran_hooke.cpp @@ -25,9 +25,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairGranHooke::PairGranHooke(LAMMPS *lmp) : PairGranHookeHistory(lmp) diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 149fa696f0..6ab64ee371 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -38,9 +38,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) @@ -311,7 +308,7 @@ void PairGranHookeHistory::allocate() void PairGranHookeHistory::settings(int narg, char **arg) { - if (narg != 6) error->all("Illegal pair_style command"); + if (narg != 6) error->all(FLERR,"Illegal pair_style command"); kn = force->numeric(arg[0]); if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0; @@ -327,7 +324,7 @@ void PairGranHookeHistory::settings(int narg, char **arg) if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 || xmu < 0.0 || xmu > 1.0 || dampflag < 0 || dampflag > 1) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -336,7 +333,7 @@ void PairGranHookeHistory::settings(int narg, char **arg) void PairGranHookeHistory::coeff(int narg, char **arg) { - if (narg > 2) error->all("Incorrect args for pair coefficients"); + if (narg > 2) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -351,7 +348,7 @@ void PairGranHookeHistory::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -365,9 +362,9 @@ void PairGranHookeHistory::init_style() // error and warning checks if (!atom->sphere_flag) - error->all("Pair granular requires atom style sphere"); + error->all(FLERR,"Pair granular requires atom style sphere"); if (comm->ghost_velocity == 0) - error->all("Pair granular requires ghost atoms store velocity"); + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); // need a half neigh list and optionally a granular history neigh list @@ -389,7 +386,7 @@ void PairGranHookeHistory::init_style() // if first init, create Fix needed for storing shear history if (history && force->newton_pair == 1) - error->all("Pair granular with shear history requires newton pair off"); + error->all(FLERR,"Pair granular with shear history requires newton pair off"); if (history && fix_history == NULL) { char **fixarg = new char*[3]; diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp index ad7a5923ec..5b6d46750a 100644 --- a/src/KSPACE/ewald.cpp +++ b/src/KSPACE/ewald.cpp @@ -33,14 +33,11 @@ using namespace LAMMPS_NS; #define SMALL 0.00001 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) { - if (narg != 1) error->all("Illegal kspace_style ewald command"); + if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command"); precision = atof(arg[0]); PI = 4.0*atan(1.0); @@ -81,18 +78,18 @@ void Ewald::init() // error check - if (domain->triclinic) error->all("Cannot use Ewald with triclinic box"); + if (domain->triclinic) error->all(FLERR,"Cannot use Ewald with triclinic box"); if (domain->dimension == 2) - error->all("Cannot use Ewald with 2d simulation"); + error->all(FLERR,"Cannot use Ewald with 2d simulation"); - if (!atom->q_flag) error->all("Kspace style requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with Ewald"); + error->all(FLERR,"Cannot use nonperiodic boundaries with Ewald"); if (slabflag == 1) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab Ewald"); + error->all(FLERR,"Incorrect boundaries with slab Ewald"); } // extract short-range Coulombic cutoff from pair style @@ -101,11 +98,11 @@ void Ewald::init() scale = 1.0; if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); int itmp; double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); if (p_cutoff == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); double cutoff = *p_cutoff; qsum = qsqsum = 0.0; @@ -121,11 +118,11 @@ void Ewald::init() qsqsum = tmp; if (qsqsum == 0.0) - error->all("Cannot use kspace solver on system with no charge"); + error->all(FLERR,"Cannot use kspace solver on system with no charge"); if (fabs(qsum) > SMALL && comm->me == 0) { char str[128]; sprintf(str,"System is not charge neutral, net charge = %g",qsum); - error->warning(str); + error->warning(FLERR,str); } // setup K-space resolution diff --git a/src/KSPACE/fft3d_wrap.cpp b/src/KSPACE/fft3d_wrap.cpp index fa0d232a10..ef1298de40 100644 --- a/src/KSPACE/fft3d_wrap.cpp +++ b/src/KSPACE/fft3d_wrap.cpp @@ -30,7 +30,7 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, scaled,permute,nbuf); - if (plan == NULL) error->one("Could not create 3d FFT plan"); + if (plan == NULL) error->one(FLERR,"Could not create 3d FFT plan"); } /* ---------------------------------------------------------------------- */ diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp index fce0ce0846..44f3d73bf9 100644 --- a/src/KSPACE/pair_born_coul_long.cpp +++ b/src/KSPACE/pair_born_coul_long.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -213,7 +210,7 @@ void PairBornCoulLong::allocate() void PairBornCoulLong::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul = cut_lj_global; @@ -235,7 +232,7 @@ void PairBornCoulLong::settings(int narg, char **arg) void PairBornCoulLong::coeff(int narg, char **arg) { - if (narg < 7 || narg > 8) error->all("Incorrect args for pair coefficients"); + if (narg < 7 || narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -245,7 +242,7 @@ void PairBornCoulLong::coeff(int narg, char **arg) double a_one = force->numeric(arg[2]); double rho_one = force->numeric(arg[3]); double sigma_one = force->numeric(arg[4]); - if (rho_one <= 0) error->all("Incorrect args for pair coefficients"); + if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients"); double c_one = force->numeric(arg[5]); double d_one = force->numeric(arg[6]); @@ -266,7 +263,7 @@ void PairBornCoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -275,7 +272,7 @@ void PairBornCoulLong::coeff(int narg, char **arg) double PairBornCoulLong::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); double cut = MAX(cut_lj[i][j],cut_coul); cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j]; @@ -345,14 +342,14 @@ double PairBornCoulLong::init_one(int i, int j) void PairBornCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style born/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style born/coul/long requires atom attribute q"); cut_coulsq = cut_coul * cut_coul; // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; neighbor->request(this); diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp index ba18aff25e..6b3e92b50d 100644 --- a/src/KSPACE/pair_buck_coul_long.cpp +++ b/src/KSPACE/pair_buck_coul_long.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -202,7 +199,7 @@ void PairBuckCoulLong::allocate() void PairBuckCoulLong::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul = cut_lj_global; @@ -224,7 +221,7 @@ void PairBuckCoulLong::settings(int narg, char **arg) void PairBuckCoulLong::coeff(int narg, char **arg) { - if (narg < 5 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -233,7 +230,7 @@ void PairBuckCoulLong::coeff(int narg, char **arg) double a_one = force->numeric(arg[2]); double rho_one = force->numeric(arg[3]); - if (rho_one <= 0) error->all("Incorrect args for pair coefficients"); + if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients"); double c_one = force->numeric(arg[4]); double cut_lj_one = cut_lj_global; @@ -251,7 +248,7 @@ void PairBuckCoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -260,7 +257,7 @@ void PairBuckCoulLong::coeff(int narg, char **arg) double PairBuckCoulLong::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); double cut = MAX(cut_lj[i][j],cut_coul); cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j]; @@ -322,14 +319,14 @@ double PairBuckCoulLong::init_one(int i, int j) void PairBuckCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style buck/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style buck/coul/long requires atom attribute q"); cut_coulsq = cut_coul * cut_coul; // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; neighbor->request(this); diff --git a/src/KSPACE/pair_coul_long.cpp b/src/KSPACE/pair_coul_long.cpp index dee833cb66..6a3f70b351 100644 --- a/src/KSPACE/pair_coul_long.cpp +++ b/src/KSPACE/pair_coul_long.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -199,7 +196,7 @@ void PairCoulLong::allocate() void PairCoulLong::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_coul = force->numeric(arg[0]); } @@ -210,7 +207,7 @@ void PairCoulLong::settings(int narg, char **arg) void PairCoulLong::coeff(int narg, char **arg) { - if (narg != 2) error->all("Incorrect args for pair coefficients"); + if (narg != 2) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -226,7 +223,7 @@ void PairCoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -236,7 +233,7 @@ void PairCoulLong::coeff(int narg, char **arg) void PairCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q"); neighbor->request(this); @@ -248,13 +245,13 @@ void PairCoulLong::init_style() ((Respa *) update->integrate)->level_inner >= 0) { cut_respa = ((Respa *) update->integrate)->cutoff; if (cut_coul < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); } else cut_respa = NULL; // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/KSPACE/pair_lj_charmm_coul_long.cpp b/src/KSPACE/pair_lj_charmm_coul_long.cpp index 539cf34f73..1ff61a5ec0 100644 --- a/src/KSPACE/pair_lj_charmm_coul_long.cpp +++ b/src/KSPACE/pair_lj_charmm_coul_long.cpp @@ -37,9 +37,6 @@ using namespace LAMMPS_NS; enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // same as in pair.cpp -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -656,7 +653,7 @@ void PairLJCharmmCoulLong::allocate() void PairLJCharmmCoulLong::settings(int narg, char **arg) { - if (narg != 2 && narg != 3) error->all("Illegal pair_style command"); + if (narg != 2 && narg != 3) error->all(FLERR,"Illegal pair_style command"); cut_lj_inner = force->numeric(arg[0]); cut_lj = force->numeric(arg[1]); @@ -670,7 +667,7 @@ void PairLJCharmmCoulLong::settings(int narg, char **arg) void PairLJCharmmCoulLong::coeff(int narg, char **arg) { - if (narg != 4 && narg != 6) error->all("Illegal pair_coeff command"); + if (narg != 4 && narg != 6) error->all(FLERR,"Illegal pair_coeff command"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -698,7 +695,7 @@ void PairLJCharmmCoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -708,7 +705,7 @@ void PairLJCharmmCoulLong::coeff(int narg, char **arg) void PairLJCharmmCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists @@ -749,7 +746,7 @@ void PairLJCharmmCoulLong::init_style() // require cut_lj_inner < cut_lj if (cut_lj_inner >= cut_lj) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; @@ -765,15 +762,15 @@ void PairLJCharmmCoulLong::init_style() ((Respa *) update->integrate)->level_inner >= 0) { cut_respa = ((Respa *) update->integrate)->cutoff; if (MIN(cut_lj,cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); if (cut_lj_inner < cut_respa[1]) - error->all("Pair inner cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair inner cutoff < Respa interior cutoff"); } else cut_respa = NULL; // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp index 7ab653b58b..ba9e390baa 100644 --- a/src/KSPACE/pair_lj_cut_coul_long.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long.cpp @@ -35,9 +35,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -593,7 +590,7 @@ void PairLJCutCoulLong::allocate() void PairLJCutCoulLong::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul = cut_lj_global; @@ -615,7 +612,7 @@ void PairLJCutCoulLong::settings(int narg, char **arg) void PairLJCutCoulLong::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -639,7 +636,7 @@ void PairLJCutCoulLong::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -649,7 +646,7 @@ void PairLJCutCoulLong::coeff(int narg, char **arg) void PairLJCutCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists @@ -699,7 +696,7 @@ void PairLJCutCoulLong::init_style() // insure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables @@ -756,7 +753,7 @@ double PairLJCutCoulLong::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && MIN(cut_lj[i][j],cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); // compute I,J contribution to long-range tail correction // count total # of atoms of type I and J via Allreduce diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp index 2df4235f59..bc3cfc98dd 100644 --- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp @@ -37,9 +37,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -369,7 +366,7 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag) void PairLJCutCoulLongTIP4P::settings(int narg, char **arg) { - if (narg < 6 || narg > 7) error->all("Illegal pair_style command"); + if (narg < 6 || narg > 7) error->all(FLERR,"Illegal pair_style command"); typeO = force->inumeric(arg[0]); typeH = force->inumeric(arg[1]); @@ -398,17 +395,17 @@ void PairLJCutCoulLongTIP4P::settings(int narg, char **arg) void PairLJCutCoulLongTIP4P::init_style() { if (atom->tag_enable == 0) - error->all("Pair style lj/cut/coul/long/tip4p requires atom IDs"); + error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires atom IDs"); if (!force->newton_pair) - error->all("Pair style lj/cut/coul/long/tip4p requires newton pair on"); + error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires newton pair on"); if (!atom->q_flag) - error->all("Pair style lj/cut/coul/long/tip4p requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires atom attribute q"); if (strcmp(force->kspace_style,"pppm/tip4p") != 0) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); if (force->bond == NULL) - error->all("Must use a bond style with TIP4P potential"); + error->all(FLERR,"Must use a bond style with TIP4P potential"); if (force->angle == NULL) - error->all("Must use an angle style with TIP4P potential"); + error->all(FLERR,"Must use an angle style with TIP4P potential"); PairLJCutCoulLong::init_style(); @@ -482,9 +479,9 @@ void PairLJCutCoulLongTIP4P::find_M(int i, int &iH1, int &iH2, double *xM) iH1 = atom->map(atom->tag[i] + 1); iH2 = atom->map(atom->tag[i] + 2); - if (iH1 == -1 || iH2 == -1) error->one("TIP4P hydrogen is missing"); + if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) - error->one("TIP4P hydrogen has incorrect atom type"); + error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); double **x = atom->x; diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 40730df6ff..cc92e1719f 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -51,14 +51,11 @@ using namespace LAMMPS_NS; #define ONEF 1.0 #endif -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) { - if (narg < 1) error->all("Illegal kspace_style pppm command"); + if (narg < 1) error->all(FLERR,"Illegal kspace_style pppm command"); precision = atof(arg[0]); PI = 4.0*atan(1.0); @@ -115,23 +112,23 @@ void PPPM::init() // error check if (domain->triclinic) - error->all("Cannot (yet) use PPPM with triclinic box"); - if (domain->dimension == 2) error->all("Cannot use PPPM with 2d simulation"); + error->all(FLERR,"Cannot (yet) use PPPM with triclinic box"); + if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPM with 2d simulation"); - if (!atom->q_flag) error->all("Kspace style requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with PPPM"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPM"); if (slabflag == 1) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab PPPM"); + error->all(FLERR,"Incorrect boundaries with slab PPPM"); } if (order > MAXORDER) { char str[128]; sprintf(str,"PPPM order cannot be greater than %d",MAXORDER); - error->all(str); + error->all(FLERR,str); } // free all arrays previously allocated @@ -144,11 +141,11 @@ void PPPM::init() scale = 1.0; if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); int itmp; double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); if (p_cutoff == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); cutoff = *p_cutoff; // if kspace is TIP4P, extract TIP4P params from pair style @@ -158,14 +155,14 @@ void PPPM::init() if (strcmp(force->kspace_style,"pppm/tip4p") == 0) { if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); double *p_qdist = (double *) force->pair->extract("qdist",itmp); int *p_typeO = (int *) force->pair->extract("typeO",itmp); int *p_typeH = (int *) force->pair->extract("typeH",itmp); int *p_typeA = (int *) force->pair->extract("typeA",itmp); int *p_typeB = (int *) force->pair->extract("typeB",itmp); if (!p_qdist || !p_typeO || !p_typeH || !p_typeA || !p_typeB) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); qdist = *p_qdist; typeO = *p_typeO; typeH = *p_typeH; @@ -173,13 +170,13 @@ void PPPM::init() int typeB = *p_typeB; if (force->angle == NULL || force->bond == NULL) - error->all("Bond and angle potentials must be defined for TIP4P"); + error->all(FLERR,"Bond and angle potentials must be defined for TIP4P"); if (typeA < 1 || typeA > atom->nangletypes || force->angle->setflag[typeA] == 0) - error->all("Bad TIP4P angle type for PPPM/TIP4P"); + error->all(FLERR,"Bad TIP4P angle type for PPPM/TIP4P"); if (typeB < 1 || typeB > atom->nbondtypes || force->bond->setflag[typeB] == 0) - error->all("Bad TIP4P bond type for PPPM/TIP4P"); + error->all(FLERR,"Bad TIP4P bond type for PPPM/TIP4P"); double theta = force->angle->equilibrium_angle(typeA); double blen = force->bond->equilibrium_distance(typeB); alpha = qdist / (cos(0.5*theta) * blen); @@ -200,11 +197,11 @@ void PPPM::init() qsqsum = tmp; if (qsqsum == 0.0) - error->all("Cannot use kspace solver on system with no charge"); + error->all(FLERR,"Cannot use kspace solver on system with no charge"); if (fabs(qsum) > SMALL && me == 0) { char str[128]; sprintf(str,"System is not charge neutral, net charge = %g",qsum); - error->warning(str); + error->warning(FLERR,str); } // setup FFT grid resolution and g_ewald @@ -216,14 +213,14 @@ void PPPM::init() while (order > 0) { if (iteration && me == 0) - error->warning("Reducing PPPM order b/c stencil extends " + error->warning(FLERR,"Reducing PPPM order b/c stencil extends " "beyond neighbor processor"); iteration++; set_grid(); if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) - error->all("PPPM grid is too large"); + error->all(FLERR,"PPPM grid is too large"); // global indices of PPPM grid range from 0 to N-1 // nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of @@ -394,7 +391,7 @@ void PPPM::init() order--; } - if (order == 0) error->all("PPPM order has been reduced to 0"); + if (order == 0) error->all(FLERR,"PPPM order has been reduced to 0"); // decomposition of FFT mesh // global indices range from 0 to N-1 @@ -946,7 +943,7 @@ void PPPM::set_grid() g_ewald = gew2; fmid = diffpr(h_x,h_y,h_z,q2,acons); - if (f*fmid >= 0.0) error->all("Cannot compute PPPM G"); + if (f*fmid >= 0.0) error->all(FLERR,"Cannot compute PPPM G"); rtb = f < 0.0 ? (dgew=gew2-gew1,gew1) : (dgew=gew1-gew2,gew2); ncount = 0; while (fabs(dgew) > SMALL && fmid != 0.0) { @@ -955,7 +952,7 @@ void PPPM::set_grid() fmid = diffpr(h_x,h_y,h_z,q2,acons); if (fmid <= 0.0) rtb = g_ewald; ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPM G"); + if (ncount > LARGE) error->all(FLERR,"Cannot compute PPPM G"); } } @@ -1499,7 +1496,7 @@ void PPPM::particle_map() nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag = 1; } - if (flag) error->one("Out of range atoms - cannot compute PPPM"); + if (flag) error->one(FLERR,"Out of range atoms - cannot compute PPPM"); } /* ---------------------------------------------------------------------- diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp index 74b29e4653..12860f7aed 100644 --- a/src/KSPACE/pppm_cg.cpp +++ b/src/KSPACE/pppm_cg.cpp @@ -40,7 +40,7 @@ using namespace LAMMPS_NS; PPPMCG::PPPMCG(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg) { - if ((narg < 1) || (narg > 2)) error->all("Illegal kspace_style pppm/cg command"); + if ((narg < 1) || (narg > 2)) error->all(FLERR,"Illegal kspace_style pppm/cg command"); if (narg == 2) smallq = atof(arg[1]); @@ -232,7 +232,7 @@ void PPPMCG::particle_map() nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag = 1; } - if (flag) error->one("Out of range atoms - cannot compute PPPM"); + if (flag) error->one(FLERR,"Out of range atoms - cannot compute PPPM"); } /* ---------------------------------------------------------------------- diff --git a/src/KSPACE/pppm_tip4p.cpp b/src/KSPACE/pppm_tip4p.cpp index af0af92fad..a191fa742c 100644 --- a/src/KSPACE/pppm_tip4p.cpp +++ b/src/KSPACE/pppm_tip4p.cpp @@ -82,7 +82,7 @@ void PPPMTIP4P::particle_map() int flag_all; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Out of range atoms - cannot compute PPPM"); + if (flag_all) error->all(FLERR,"Out of range atoms - cannot compute PPPM"); } /* ---------------------------------------------------------------------- @@ -253,9 +253,9 @@ void PPPMTIP4P::find_M(int i, int &iH1, int &iH2, double *xM) iH1 = atom->map(atom->tag[i] + 1); iH2 = atom->map(atom->tag[i] + 2); - if (iH1 == -1 || iH2 == -1) error->one("TIP4P hydrogen is missing"); + if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) - error->one("TIP4P hydrogen has incorrect atom type"); + error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); double **x = atom->x; diff --git a/src/KSPACE/remap_wrap.cpp b/src/KSPACE/remap_wrap.cpp index 83631defe4..679c2a8365 100644 --- a/src/KSPACE/remap_wrap.cpp +++ b/src/KSPACE/remap_wrap.cpp @@ -30,7 +30,7 @@ Remap::Remap(LAMMPS *lmp, MPI_Comm comm, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, nqty,permute,memory,precision); - if (plan == NULL) error->one("Could not create 3d remap plan"); + if (plan == NULL) error->one(FLERR,"Could not create 3d remap plan"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MANYBODY/fix_qeq_comb.cpp b/src/MANYBODY/fix_qeq_comb.cpp index d1537f78bf..7d36ee157e 100644 --- a/src/MANYBODY/fix_qeq_comb.cpp +++ b/src/MANYBODY/fix_qeq_comb.cpp @@ -32,14 +32,11 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixQEQComb::FixQEQComb(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix qeq/comb command"); + if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb command"); peratom_flag = 1; size_peratom_cols = 0; @@ -49,7 +46,7 @@ FixQEQComb::FixQEQComb(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) precision = force->numeric(arg[4]); if (nevery <= 0 || precision <= 0.0) - error->all("Illegal fix qeq/comb command"); + error->all(FLERR,"Illegal fix qeq/comb command"); MPI_Comm_rank(world,&me); @@ -60,17 +57,17 @@ FixQEQComb::FixQEQComb(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) int iarg = 5; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all("Illegal fix qeq/comb command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix qeq/comb command"); if (me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix qeq/comb file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; - } else error->all("Illegal fix qeq/comb command"); + } else error->all(FLERR,"Illegal fix qeq/comb command"); } nmax = atom->nmax; @@ -111,16 +108,16 @@ int FixQEQComb::setmask() void FixQEQComb::init() { if (!atom->q_flag) - error->all("Fix qeq/comb requires atom attribute q"); + error->all(FLERR,"Fix qeq/comb requires atom attribute q"); comb = (PairComb *) force->pair_match("comb",1); - if (comb == NULL) error->all("Must use pair_style comb with fix qeq/comb"); + if (comb == NULL) error->all(FLERR,"Must use pair_style comb with fix qeq/comb"); if (strstr(update->integrate_style,"respa")) nlevels_respa = ((Respa *) update->integrate)->nlevels; ngroup = group->count(igroup); - if (ngroup == 0) error->all("Fix qeq/comb group has no atoms"); + if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MANYBODY/pair_adp.cpp b/src/MANYBODY/pair_adp.cpp index c2823c73e8..0f6b0a6a9d 100644 --- a/src/MANYBODY/pair_adp.cpp +++ b/src/MANYBODY/pair_adp.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 1024 /* ---------------------------------------------------------------------- */ @@ -423,7 +420,7 @@ void PairADP::allocate() void PairADP::settings(int narg, char **arg) { - if (narg > 0) error->all("Illegal pair_style command"); + if (narg > 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -438,12 +435,12 @@ void PairADP::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read ADP parameter file @@ -472,7 +469,7 @@ void PairADP::coeff(int narg, char **arg) for (j = 0; j < setfl->nelements; j++) if (strcmp(arg[i],setfl->elements[j]) == 0) break; if (j < setfl->nelements) map[i-2] = j; - else error->all("No matching element in ADP potential file"); + else error->all(FLERR,"No matching element in ADP potential file"); } // clear setflag since coeff() called once with I,J = * * @@ -496,7 +493,7 @@ void PairADP::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -549,7 +546,7 @@ void PairADP::read_file(char *filename) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open ADP potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -570,7 +567,7 @@ void PairADP::read_file(char *filename) sscanf(line,"%d",&file->nelements); int nwords = atom->count_words(line); if (nwords != file->nelements + 1) - error->all("Incorrect element names in ADP potential file"); + error->all(FLERR,"Incorrect element names in ADP potential file"); char **words = new char*[file->nelements+1]; nwords = 0; diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index 427495433c..e8c623b47b 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 1024 #define TOL 1.0e-9 #define PGDELTA 1 @@ -135,7 +132,7 @@ void PairAIREBO::allocate() void PairAIREBO::settings(int narg, char **arg) { - if (narg != 1 && narg != 3) error->all("Illegal pair_style command"); + if (narg != 1 && narg != 3) error->all(FLERR,"Illegal pair_style command"); cutlj = force->numeric(arg[0]); @@ -155,12 +152,12 @@ void PairAIREBO::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to C and H // map[i] = which element (0,1) the Ith atom type is, -1 if NULL @@ -173,7 +170,7 @@ void PairAIREBO::coeff(int narg, char **arg) map[i-2] = 0; } else if (strcmp(arg[i],"H") == 0) { map[i-2] = 1; - } else error->all("Incorrect args for pair coefficients"); + } else error->all(FLERR,"Incorrect args for pair coefficients"); } // read potential file and initialize fitting splines @@ -198,7 +195,7 @@ void PairAIREBO::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -208,9 +205,9 @@ void PairAIREBO::coeff(int narg, char **arg) void PairAIREBO::init_style() { if (atom->tag_enable == 0) - error->all("Pair style AIREBO requires atom IDs"); + error->all(FLERR,"Pair style AIREBO requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style AIREBO requires newton pair on"); + error->all(FLERR,"Pair style AIREBO requires newton pair on"); // need a full neighbor list, including neighbors of ghosts @@ -232,7 +229,7 @@ void PairAIREBO::init_style() double PairAIREBO::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); // convert to C,H types @@ -371,7 +368,7 @@ void PairAIREBO::REBO_neigh() REBO_numneigh[i] = n; npnt += n; if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } } @@ -3401,7 +3398,7 @@ void PairAIREBO::read_file(char *filename) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open AIREBO potential file %s",filename); - error->one(str); + error->one(FLERR,str); } // skip initial comment lines diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 4b203731fd..5d0db94997 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -417,7 +417,7 @@ void PairComb::allocate() void PairComb::settings(int narg, char **arg) { - if (narg > 0) error->all("Illegal pair_style command"); + if (narg > 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -431,12 +431,12 @@ void PairComb::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to elements in potential file // map[i] = which element the Ith atom type is, -1 if NULL @@ -502,7 +502,7 @@ void PairComb::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -512,11 +512,11 @@ void PairComb::coeff(int narg, char **arg) void PairComb::init_style() { if (atom->tag_enable == 0) - error->all("Pair style COMB requires atom IDs"); + error->all(FLERR,"Pair style COMB requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style COMB requires newton pair on"); + error->all(FLERR,"Pair style COMB requires newton pair on"); if (!atom->q_flag) - error->all("Pair style COMB requires atom attribute q"); + error->all(FLERR,"Pair style COMB requires atom attribute q"); // ptr to QEQ fix @@ -538,7 +538,7 @@ void PairComb::init_style() double PairComb::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); return cutmax; } @@ -561,7 +561,7 @@ void PairComb::read_file(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open COMB potential file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -611,7 +611,7 @@ void PairComb::read_file(char *file) } if (nwords != params_per_line) - error->all("Incorrect format in COMB potential file"); + error->all(FLERR,"Incorrect format in COMB potential file"); // words = ptrs to all words in line @@ -719,13 +719,13 @@ void PairComb::read_file(char *file) // params[nparams].dj < 0.0 || params[nparams].dk < 0.0 || // params[nparams].dl < 0.0 || params[nparams].dm < 0.0 || params[nparams].esm1 < 0.0) - error->all("Illegal COMB parameter"); + error->all(FLERR,"Illegal COMB parameter"); if (params[nparams].lam11 < params[nparams].lam21 || params[nparams].lam12 < params[nparams].lam22 || params[nparams].biga1< params[nparams].bigb1 || params[nparams].biga2< params[nparams].bigb2) - error->all("Illegal COMB parameter"); + error->all(FLERR,"Illegal COMB parameter"); nparams++; } @@ -753,11 +753,11 @@ void PairComb::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all("Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all("Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry"); elem2param[i][j][k] = n; } @@ -1779,14 +1779,14 @@ double PairComb::qfo_self(Param *param, double qi, double selfpot) // char str[128]; // sprintf(str,"Pair COMB charge %.10f with force %.10f hit min barrier", // qi,self_d); - // error->warning(str,0); + // error->warning(FLERR,str,0); self_d += 4.0 * cmin * pow((qi-qmin),3); } if (qi > qmax) { // char str[128]; // sprintf(str,"Pair COMB charge %.10f with force %.10f hit max barrier", // qi,self_d); - // error->warning(str,0); + // error->warning(FLERR,str,0); self_d += 4.0 * cmax * pow((qi-qmax),3); } diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp index bc87ad4b85..39a8292bc1 100644 --- a/src/MANYBODY/pair_eam.cpp +++ b/src/MANYBODY/pair_eam.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 1024 /* ---------------------------------------------------------------------- */ @@ -332,7 +329,7 @@ void PairEAM::allocate() void PairEAM::settings(int narg, char **arg) { - if (narg > 0) error->all("Illegal pair_style command"); + if (narg > 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -344,7 +341,7 @@ void PairEAM::coeff(int narg, char **arg) { if (!allocated) allocate(); - if (narg != 3) error->all("Incorrect args for pair coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for pair coefficients"); // parse pair of atom types @@ -384,7 +381,7 @@ void PairEAM::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -440,7 +437,7 @@ void PairEAM::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } diff --git a/src/MANYBODY/pair_eam_alloy.cpp b/src/MANYBODY/pair_eam_alloy.cpp index 0584022586..5b6cd72f51 100644 --- a/src/MANYBODY/pair_eam_alloy.cpp +++ b/src/MANYBODY/pair_eam_alloy.cpp @@ -47,12 +47,12 @@ void PairEAMAlloy::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read EAM setfl file @@ -79,7 +79,7 @@ void PairEAMAlloy::coeff(int narg, char **arg) for (j = 0; j < setfl->nelements; j++) if (strcmp(arg[i],setfl->elements[j]) == 0) break; if (j < setfl->nelements) map[i-2] = j; - else error->all("No matching element in EAM potential file"); + else error->all(FLERR,"No matching element in EAM potential file"); } // clear setflag since coeff() called once with I,J = * * @@ -103,7 +103,7 @@ void PairEAMAlloy::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -125,7 +125,7 @@ void PairEAMAlloy::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -146,7 +146,7 @@ void PairEAMAlloy::read_file(char *filename) sscanf(line,"%d",&file->nelements); int nwords = atom->count_words(line); if (nwords != file->nelements + 1) - error->all("Incorrect element names in EAM potential file"); + error->all(FLERR,"Incorrect element names in EAM potential file"); char **words = new char*[file->nelements+1]; nwords = 0; diff --git a/src/MANYBODY/pair_eam_fs.cpp b/src/MANYBODY/pair_eam_fs.cpp index ccd4d7e30d..0ac0768b98 100644 --- a/src/MANYBODY/pair_eam_fs.cpp +++ b/src/MANYBODY/pair_eam_fs.cpp @@ -47,12 +47,12 @@ void PairEAMFS::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read EAM Finnis-Sinclair file @@ -79,7 +79,7 @@ void PairEAMFS::coeff(int narg, char **arg) for (j = 0; j < fs->nelements; j++) if (strcmp(arg[i],fs->elements[j]) == 0) break; if (j < fs->nelements) map[i-2] = j; - else error->all("No matching element in EAM potential file"); + else error->all(FLERR,"No matching element in EAM potential file"); } // clear setflag since coeff() called once with I,J = * * @@ -103,7 +103,7 @@ void PairEAMFS::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -125,7 +125,7 @@ void PairEAMFS::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -146,7 +146,7 @@ void PairEAMFS::read_file(char *filename) sscanf(line,"%d",&file->nelements); int nwords = atom->count_words(line); if (nwords != file->nelements + 1) - error->all("Incorrect element names in EAM potential file"); + error->all(FLERR,"Incorrect element names in EAM potential file"); char **words = new char*[file->nelements+1]; nwords = 0; diff --git a/src/MANYBODY/pair_eim.cpp b/src/MANYBODY/pair_eim.cpp index 07c2706c06..c8b324d264 100644 --- a/src/MANYBODY/pair_eim.cpp +++ b/src/MANYBODY/pair_eim.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 1024 /* ---------------------------------------------------------------------- */ @@ -344,7 +341,7 @@ void PairEIM::allocate() void PairEIM::settings(int narg, char **arg) { - if (narg > 0) error->all("Illegal pair_style command"); + if (narg > 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -357,12 +354,12 @@ void PairEIM::coeff(int narg, char **arg) if (!allocated) allocate(); - if (narg < 5) error->all("Incorrect args for pair coefficients"); + if (narg < 5) error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read EIM element names before filename // nelements = # of EIM elements to read from file @@ -373,7 +370,7 @@ void PairEIM::coeff(int narg, char **arg) delete [] elements; } nelements = narg - 3 - atom->ntypes; - if (nelements < 1) error->all("Incorrect args for pair coefficients"); + if (nelements < 1) error->all(FLERR,"Incorrect args for pair coefficients"); elements = new char*[nelements]; for (i = 0; i < nelements; i++) { @@ -397,7 +394,7 @@ void PairEIM::coeff(int narg, char **arg) if (strcmp(arg[i],elements[j]) == 0) break; if (j < nelements) map[m] = j; else if (strcmp(arg[i],"NULL") == 0) map[m] = -1; - else error->all("Incorrect args for pair coefficients"); + else error->all(FLERR,"Incorrect args for pair coefficients"); } // clear setflag since coeff() called once with I,J = * * @@ -419,7 +416,7 @@ void PairEIM::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -462,7 +459,7 @@ void PairEIM::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EIM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -491,7 +488,7 @@ void PairEIM::read_file(char *filename) if (me == 0) if (!grabglobal(fptr)) - error->one("Could not grab global entry from EIM potential file"); + error->one(FLERR,"Could not grab global entry from EIM potential file"); MPI_Bcast(&setfl->division,1,MPI_DOUBLE,0,world); MPI_Bcast(&setfl->rbig,1,MPI_DOUBLE,0,world); MPI_Bcast(&setfl->rsmall,1,MPI_DOUBLE,0,world); @@ -499,7 +496,7 @@ void PairEIM::read_file(char *filename) for (int i = 0; i < nelements; i++) { if (me == 0) if (!grabsingle(fptr,i)) - error->one("Could not grab element entry from EIM potential file"); + error->one(FLERR,"Could not grab element entry from EIM potential file"); MPI_Bcast(&setfl->ielement[i],1,MPI_INT,0,world); MPI_Bcast(&setfl->mass[i],1,MPI_DOUBLE,0,world); MPI_Bcast(&setfl->negativity[i],1,MPI_DOUBLE,0,world); @@ -517,7 +514,7 @@ void PairEIM::read_file(char *filename) else ij = nelements*(j+1) - (j+1)*(j+2)/2 + i; if (me == 0) if (grabpair(fptr,i,j) == 0) - error->one("Could not grab pair entry from EIM potential file"); + error->one(FLERR,"Could not grab pair entry from EIM potential file"); MPI_Bcast(&setfl->rcutphiA[ij],1,MPI_DOUBLE,0,world); MPI_Bcast(&setfl->rcutphiR[ij],1,MPI_DOUBLE,0,world); MPI_Bcast(&setfl->Eb[ij],1,MPI_DOUBLE,0,world); diff --git a/src/MANYBODY/pair_rebo.cpp b/src/MANYBODY/pair_rebo.cpp index 5a73f7bda0..efda8c2c9e 100644 --- a/src/MANYBODY/pair_rebo.cpp +++ b/src/MANYBODY/pair_rebo.cpp @@ -27,7 +27,7 @@ PairREBO::PairREBO(LAMMPS *lmp) : PairAIREBO(lmp) {} void PairREBO::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); cutlj = 0.0; ljflag = torflag = 0; diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index c0661cc1a1..1c708564ac 100755 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -215,7 +215,7 @@ void PairSW::allocate() void PairSW::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -229,12 +229,12 @@ void PairSW::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to elements in potential file // map[i] = which element the Ith atom type is, -1 if NULL @@ -287,7 +287,7 @@ void PairSW::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -297,9 +297,9 @@ void PairSW::coeff(int narg, char **arg) void PairSW::init_style() { if (atom->tag_enable == 0) - error->all("Pair style Stillinger-Weber requires atom IDs"); + error->all(FLERR,"Pair style Stillinger-Weber requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style Stillinger-Weber requires newton pair on"); + error->all(FLERR,"Pair style Stillinger-Weber requires newton pair on"); // need a full neighbor list @@ -314,7 +314,7 @@ void PairSW::init_style() double PairSW::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); return cutmax; } @@ -338,7 +338,7 @@ void PairSW::read_file(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open Stillinger-Weber potential file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -389,7 +389,7 @@ void PairSW::read_file(char *file) } if (nwords != params_per_line) - error->all("Incorrect format in Stillinger-Weber potential file"); + error->all(FLERR,"Incorrect format in Stillinger-Weber potential file"); // words = ptrs to all words in line @@ -439,7 +439,7 @@ void PairSW::read_file(char *file) params[nparams].gamma < 0.0 || params[nparams].biga < 0.0 || params[nparams].bigb < 0.0 || params[nparams].powerp < 0.0 || params[nparams].powerq < 0.0 || params[nparams].tol < 0.0) - error->all("Illegal Stillinger-Weber parameter"); + error->all(FLERR,"Illegal Stillinger-Weber parameter"); nparams++; } @@ -468,11 +468,11 @@ void PairSW::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all("Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all("Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry"); elem2param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index b6e8819406..bd50ec9bd3 100755 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -256,7 +256,7 @@ void PairTersoff::allocate() void PairTersoff::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -270,12 +270,12 @@ void PairTersoff::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to elements in potential file // map[i] = which element the Ith atom type is, -1 if NULL @@ -328,7 +328,7 @@ void PairTersoff::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -338,9 +338,9 @@ void PairTersoff::coeff(int narg, char **arg) void PairTersoff::init_style() { if (atom->tag_enable == 0) - error->all("Pair style Tersoff requires atom IDs"); + error->all(FLERR,"Pair style Tersoff requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style Tersoff requires newton pair on"); + error->all(FLERR,"Pair style Tersoff requires newton pair on"); // need a full neighbor list @@ -355,7 +355,7 @@ void PairTersoff::init_style() double PairTersoff::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); return cutmax; } @@ -379,7 +379,7 @@ void PairTersoff::read_file(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open Tersoff potential file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -429,7 +429,7 @@ void PairTersoff::read_file(char *file) } if (nwords != params_per_line) - error->all("Incorrect format in Tersoff potential file"); + error->all(FLERR,"Incorrect format in Tersoff potential file"); // words = ptrs to all words in line @@ -490,7 +490,7 @@ void PairTersoff::read_file(char *file) params[nparams].powerm - params[nparams].powermint != 0.0 || (params[nparams].powermint != 3 && params[nparams].powermint != 1) || params[nparams].gamma < 0.0) - error->all("Illegal Tersoff parameter"); + error->all(FLERR,"Illegal Tersoff parameter"); nparams++; } @@ -518,11 +518,11 @@ void PairTersoff::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all("Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all("Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry"); elem2param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_tersoff_zbl.cpp b/src/MANYBODY/pair_tersoff_zbl.cpp index dfa0da021e..90ccfd9c11 100644 --- a/src/MANYBODY/pair_tersoff_zbl.cpp +++ b/src/MANYBODY/pair_tersoff_zbl.cpp @@ -54,7 +54,7 @@ PairTersoffZBL::PairTersoffZBL(LAMMPS *lmp) : PairTersoff(lmp) global_a_0 = 0.529; global_epsilon_0 = 0.00552635 * 0.043365121; global_e = 1.0; - } else error->all("Pair tersoff/zbl requires metal or real units"); + } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units"); } /* ---------------------------------------------------------------------- */ @@ -76,7 +76,7 @@ void PairTersoffZBL::read_file(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open Tersoff potential file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -126,7 +126,7 @@ void PairTersoffZBL::read_file(char *file) } if (nwords != params_per_line) - error->all("Incorrect format in Tersoff potential file"); + error->all(FLERR,"Incorrect format in Tersoff potential file"); // words = ptrs to all words in line @@ -195,7 +195,7 @@ void PairTersoffZBL::read_file(char *file) params[nparams].gamma < 0.0 || params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 || params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0) - error->all("Illegal Tersoff parameter"); + error->all(FLERR,"Illegal Tersoff parameter"); nparams++; } diff --git a/src/MC/fix_bond_break.cpp b/src/MC/fix_bond_break.cpp index a4c44338da..888c247da7 100755 --- a/src/MC/fix_bond_break.cpp +++ b/src/MC/fix_bond_break.cpp @@ -29,20 +29,17 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix bond/break command"); + if (narg < 6) error->all(FLERR,"Illegal fix bond/break command"); MPI_Comm_rank(world,&me); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix bond/break command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix bond/break command"); force_reneighbor = 1; next_reneighbor = -1; @@ -55,8 +52,8 @@ FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) : double cutoff = atof(arg[5]); if (btype < 1 || btype > atom->nbondtypes) - error->all("Invalid bond type in fix bond/break command"); - if (cutoff < 0.0) error->all("Illegal fix bond/break command"); + error->all(FLERR,"Invalid bond type in fix bond/break command"); + if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/break command"); cutsq = cutoff*cutoff; @@ -68,20 +65,20 @@ FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"prob") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/break command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/break command"); fraction = atof(arg[iarg+1]); seed = atoi(arg[iarg+2]); if (fraction < 0.0 || fraction > 1.0) - error->all("Illegal fix bond/break command"); - if (seed <= 0) error->all("Illegal fix bond/break command"); + error->all(FLERR,"Illegal fix bond/break command"); + if (seed <= 0) error->all(FLERR,"Illegal fix bond/break command"); iarg += 3; - } else error->all("Illegal fix bond/break command"); + } else error->all(FLERR,"Illegal fix bond/break command"); } // error check if (atom->molecular == 0) - error->all("Cannot use fix bond/break with non-molecular systems"); + error->all(FLERR,"Cannot use fix bond/break with non-molecular systems"); // initialize Marsaglia RNG with processor-unique seed @@ -137,13 +134,13 @@ void FixBondBreak::init() force->special_lj[3] != 1.0) flag = 1; if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || force->special_coul[3] != 1.0) flag = 1; - if (flag) error->all("Fix bond/break requires special_bonds = 0,1,1"); + if (flag) error->all(FLERR,"Fix bond/break requires special_bonds = 0,1,1"); // warn if angles, dihedrals, impropers are being used if (force->angle || force->dihedral || force->improper) { if (me == 0) - error->warning("Broken bonds will not alter angles, " + error->warning(FLERR,"Broken bonds will not alter angles, " "dihedrals, or impropers"); } diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp index 295f04981b..042ff80dbc 100755 --- a/src/MC/fix_bond_create.cpp +++ b/src/MC/fix_bond_create.cpp @@ -33,20 +33,17 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 8) error->all("Illegal fix bond/create command"); + if (narg < 8) error->all(FLERR,"Illegal fix bond/create command"); MPI_Comm_rank(world,&me); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix bond/create command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix bond/create command"); force_reneighbor = 1; next_reneighbor = -1; @@ -62,10 +59,10 @@ FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : if (iatomtype < 1 || iatomtype > atom->ntypes || jatomtype < 1 || jatomtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); - if (cutoff < 0.0) error->all("Illegal fix bond/create command"); + error->all(FLERR,"Invalid atom type in fix bond/create command"); + if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/create command"); if (btype < 1 || btype > atom->nbondtypes) - error->all("Invalid bond type in fix bond/create command"); + error->all(FLERR,"Invalid bond type in fix bond/create command"); cutsq = cutoff*cutoff; @@ -81,39 +78,39 @@ FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : int iarg = 8; while (iarg < narg) { if (strcmp(arg[iarg],"iparam") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/create command"); imaxbond = atoi(arg[iarg+1]); inewtype = atoi(arg[iarg+2]); - if (imaxbond < 0) error->all("Illegal fix bond/create command"); + if (imaxbond < 0) error->all(FLERR,"Illegal fix bond/create command"); if (inewtype < 1 || inewtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); + error->all(FLERR,"Invalid atom type in fix bond/create command"); iarg += 3; } else if (strcmp(arg[iarg],"jparam") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/create command"); jmaxbond = atoi(arg[iarg+1]); jnewtype = atoi(arg[iarg+2]); - if (jmaxbond < 0) error->all("Illegal fix bond/create command"); + if (jmaxbond < 0) error->all(FLERR,"Illegal fix bond/create command"); if (jnewtype < 1 || jnewtype > atom->ntypes) - error->all("Invalid atom type in fix bond/create command"); + error->all(FLERR,"Invalid atom type in fix bond/create command"); iarg += 3; } else if (strcmp(arg[iarg],"prob") == 0) { - if (iarg+3 > narg) error->all("Illegal fix bond/create command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/create command"); fraction = atof(arg[iarg+1]); seed = atoi(arg[iarg+2]); if (fraction < 0.0 || fraction > 1.0) - error->all("Illegal fix bond/create command"); - if (seed <= 0) error->all("Illegal fix bond/create command"); + error->all(FLERR,"Illegal fix bond/create command"); + if (seed <= 0) error->all(FLERR,"Illegal fix bond/create command"); iarg += 3; - } else error->all("Illegal fix bond/create command"); + } else error->all(FLERR,"Illegal fix bond/create command"); } // error check if (atom->molecular == 0) - error->all("Cannot use fix bond/create with non-molecular systems"); + error->all(FLERR,"Cannot use fix bond/create with non-molecular systems"); if (iatomtype == jatomtype && ((imaxbond != jmaxbond) || (inewtype != jnewtype))) - error->all("Inconsistent iparam/jparam values in fix bond/create command"); + error->all(FLERR,"Inconsistent iparam/jparam values in fix bond/create command"); // initialize Marsaglia RNG with processor-unique seed @@ -179,24 +176,24 @@ void FixBondCreate::init() // check cutoff for iatomtype,jatomtype if (force->pair == NULL || cutsq > force->pair->cutsq[iatomtype][jatomtype]) - error->all("Fix bond/create cutoff is longer than pairwise cutoff"); + error->all(FLERR,"Fix bond/create cutoff is longer than pairwise cutoff"); // require special bonds = 0,1,1 if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) - error->all("Fix bond/create requires special_bonds lj = 0,1,1"); + error->all(FLERR,"Fix bond/create requires special_bonds lj = 0,1,1"); if (atom->q_flag) if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 || force->special_coul[3] != 1.0) - error->all("Fix bond/create requires special_bonds coul = 0,1,1"); + error->all(FLERR,"Fix bond/create requires special_bonds coul = 0,1,1"); // warn if angles, dihedrals, impropers are being used if (force->angle || force->dihedral || force->improper) { if (me == 0) - error->warning("Created bonds will not create angles, " + error->warning(FLERR,"Created bonds will not create angles, " "dihedrals, or impropers"); } @@ -251,7 +248,7 @@ void FixBondCreate::setup(int vflag) if (newton_bond) { m = atom->map(bond_atom[i][j]); if (m < 0) - error->one("Could not count initial bonds in fix bond/create"); + error->one(FLERR,"Could not count initial bonds in fix bond/create"); bondcount[m]++; } } @@ -411,7 +408,7 @@ void FixBondCreate::post_integrate() if (!newton_bond || tag[i] < tag[j]) { if (num_bond[i] == atom->bond_per_atom) - error->one("New bond exceeded bonds per atom in fix bond/create"); + error->one(FLERR,"New bond exceeded bonds per atom in fix bond/create"); bond_type[i][num_bond[i]] = btype; bond_atom[i][num_bond[i]] = tag[j]; num_bond[i]++; @@ -424,7 +421,7 @@ void FixBondCreate::post_integrate() n1 = nspecial[i][0]; n3 = nspecial[i][2]; if (n3 == atom->maxspecial) - error->one("New bond exceeded special list size in fix bond/create"); + error->one(FLERR,"New bond exceeded special list size in fix bond/create"); for (m = n3; m > n1; m--) slist[m+1] = slist[m]; slist[n1] = tag[j]; nspecial[i][0]++; diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp index daf9b13501..1984f9f40b 100644 --- a/src/MC/fix_bond_swap.cpp +++ b/src/MC/fix_bond_swap.cpp @@ -41,7 +41,7 @@ using namespace LAMMPS_NS; FixBondSwap::FixBondSwap(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix bond/swap command"); + if (narg != 6) error->all(FLERR,"Illegal fix bond/swap command"); vector_flag = 1; size_vector = 2; @@ -111,11 +111,11 @@ void FixBondSwap::init() // require an atom style with molecule IDs if (atom->molecule == NULL) - error->all("Must use atom style with molecule IDs with fix bond/swap"); + error->all(FLERR,"Must use atom style with molecule IDs with fix bond/swap"); int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix bond/swap does not exist"); + error->all(FLERR,"Temperature ID for fix bond/swap does not exist"); temperature = modify->compute[icompute]; // pair and bonds must be defined @@ -123,20 +123,20 @@ void FixBondSwap::init() // special bonds must be 0 1 1 if (force->pair == NULL || force->bond == NULL) - error->all("Fix bond/swap requires pair and bond styles"); + error->all(FLERR,"Fix bond/swap requires pair and bond styles"); if (force->pair->single_enable == 0) - error->all("Pair style does not support fix bond/swap"); + error->all(FLERR,"Pair style does not support fix bond/swap"); if (force->angle == NULL && atom->nangles > 0 && comm->me == 0) - error->warning("Fix bond/swap will ignore defined angles"); + error->warning(FLERR,"Fix bond/swap will ignore defined angles"); if (force->dihedral || force->improper) - error->all("Fix bond/swap cannot use dihedral or improper styles"); + error->all(FLERR,"Fix bond/swap cannot use dihedral or improper styles"); if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) - error->all("Fix bond/swap requires special_bonds = 0,1,1"); + error->all(FLERR,"Fix bond/swap requires special_bonds = 0,1,1"); // need a half neighbor list, built when ever re-neighboring occurs @@ -596,7 +596,7 @@ void FixBondSwap::pre_neighbor() int FixBondSwap::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -607,13 +607,13 @@ int FixBondSwap::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index 9f3dfc5e82..9016a26b28 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -40,7 +40,7 @@ using namespace LAMMPS_NS; FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 11) error->all("Illegal fix GCMC command"); + if (narg < 11) error->all(FLERR,"Illegal fix GCMC command"); vector_flag = 1; size_vector = 6; @@ -61,12 +61,12 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : displace = atof(arg[10]); if (ntype <= 0 || ntype > atom->ntypes) - error->all("Invalid atom type in fix GCMC command"); - if (nexchanges < 0) error->all("Illegal fix GCMC command"); - if (nmcmoves < 0) error->all("Illegal fix GCMC command"); - if (seed <= 0) error->all("Illegal fix GCMC command"); - if (reservoir_temperature < 0.0) error->all("Illegal fix GCMC command"); - if (displace < 0.0) error->all("Illegal fix GCMC command"); + error->all(FLERR,"Invalid atom type in fix GCMC command"); + if (nexchanges < 0) error->all(FLERR,"Illegal fix GCMC command"); + if (nmcmoves < 0) error->all(FLERR,"Illegal fix GCMC command"); + if (seed <= 0) error->all(FLERR,"Illegal fix GCMC command"); + if (reservoir_temperature < 0.0) error->all(FLERR,"Illegal fix GCMC command"); + if (displace < 0.0) error->all(FLERR,"Illegal fix GCMC command"); // compute beta, lambda, sigma, and the zz factor @@ -157,7 +157,7 @@ void FixGCMC::init() MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall) - error->all("Cannot do GCMC on atoms in atom_modify first group"); + error->all(FLERR,"Cannot do GCMC on atoms in atom_modify first group"); } // if molflag not set, warn if any deletable atom has a mol ID @@ -173,16 +173,16 @@ void FixGCMC::init() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && comm->me == 0) - error->warning("Fix GCMC may delete atom with non-zero molecule ID"); + error->warning(FLERR,"Fix GCMC may delete atom with non-zero molecule ID"); } if (molflag && atom->molecule_flag == 0) - error->all("Fix GCMC molecule command requires atom attribute molecule"); + error->all(FLERR,"Fix GCMC molecule command requires atom attribute molecule"); - if (molflag != 0) error->all("Fix GCMC molecule feature does not yet work"); + if (molflag != 0) error->all(FLERR,"Fix GCMC molecule feature does not yet work"); if (force->pair->single_enable == 0) - error->all("Fix GCMC incompatible with given pair_style"); + error->all(FLERR,"Fix GCMC incompatible with given pair_style"); } /* ---------------------------------------------------------------------- @@ -485,17 +485,17 @@ double FixGCMC::energy(int i, double *coord) void FixGCMC::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal fix GCMC command"); + if (narg < 0) error->all(FLERR,"Illegal fix GCMC command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"molecule") == 0) { - if (iarg+2 > narg) error->all("Illegal fix GCMC command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix GCMC command"); if (strcmp(arg[iarg+1],"no") == 0) molflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) molflag = 1; - else error->all("Illegal fix evaporate command"); + else error->all(FLERR,"Illegal fix evaporate command"); iarg += 2; - } else error->all("Illegal fix GCMC command"); + } else error->all(FLERR,"Illegal fix GCMC command"); } } diff --git a/src/MC/pair_dsmc.cpp b/src/MC/pair_dsmc.cpp index b04dd8f6d7..39a0f50133 100644 --- a/src/MC/pair_dsmc.cpp +++ b/src/MC/pair_dsmc.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairDSMC::PairDSMC(LAMMPS *lmp) : Pair(lmp) @@ -157,9 +154,9 @@ void PairDSMC::compute(int eflag, int vflag) convert_double_to_equivalent_int(num_of_collisions_double); if (num_of_collisions > number_of_A) - error->warning("Pair dsmc: num_of_collisions > number_of_A",0); + error->warning(FLERR,"Pair dsmc: num_of_collisions > number_of_A",0); if (num_of_collisions > number_of_B) - error->warning("Pair dsmc: num_of_collisions > number_of_B",0); + error->warning(FLERR,"Pair dsmc: num_of_collisions > number_of_B",0); // perform collisions on pairs of particles in icell @@ -208,7 +205,7 @@ void PairDSMC::allocate() void PairDSMC::settings(int narg, char **arg) { - if (narg != 6) error->all("Illegal pair_style command"); + if (narg != 6) error->all(FLERR,"Illegal pair_style command"); cut_global = 0.0; max_cell_size = force->numeric(arg[0]); @@ -220,8 +217,8 @@ void PairDSMC::settings(int narg, char **arg) // initialize Marsaglia RNG with processor-unique seed - if (max_cell_size <= 0.0) error->all("Illegal pair_style command"); - if (seed <= 0) error->all("Illegal pair_style command"); + if (max_cell_size <= 0.0) error->all(FLERR,"Illegal pair_style command"); + if (seed <= 0) error->all(FLERR,"Illegal pair_style command"); if (random) delete random; random = new RanMars(lmp,seed + comm->me); @@ -243,7 +240,7 @@ void PairDSMC::settings(int narg, char **arg) void PairDSMC::coeff(int narg, char **arg) { - if (narg < 3 || narg > 4) error->all("Incorrect args for pair coefficients"); + if (narg < 3 || narg > 4) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -265,7 +262,7 @@ void PairDSMC::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -518,7 +515,7 @@ void PairDSMC::scatter_random(int i, int j, int icell) int PairDSMC::convert_double_to_equivalent_int(double input_double) { if (input_double > INT_MAX) - error->all("Tried to convert a double to int, but input_double > INT_MAX"); + error->all(FLERR,"Tried to convert a double to int, but input_double > INT_MAX"); int output_int = static_cast(input_double + random->uniform()); return output_int; diff --git a/src/MEAM/pair_meam.cpp b/src/MEAM/pair_meam.cpp index 7c6fd9dbb2..370a719a2e 100644 --- a/src/MEAM/pair_meam.cpp +++ b/src/MEAM/pair_meam.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 1024 enum{FCC,BCC,HCP,DIM,DIAMOND,B1,C11,L12,B2}; @@ -247,7 +244,7 @@ void PairMEAM::compute(int eflag, int vflag) if (errorflag) { char str[128]; sprintf(str,"MEAM library error %d",errorflag); - error->one(str); + error->one(FLERR,str); } offset += numneigh_half[i]; } @@ -262,7 +259,7 @@ void PairMEAM::compute(int eflag, int vflag) if (errorflag) { char str[128]; sprintf(str,"MEAM library error %d",errorflag); - error->one(str); + error->one(FLERR,str); } comm->forward_comm_pair(this); @@ -290,7 +287,7 @@ void PairMEAM::compute(int eflag, int vflag) if (errorflag) { char str[128]; sprintf(str,"MEAM library error %d",errorflag); - error->one(str); + error->one(FLERR,str); } offset += numneigh_half[i]; } @@ -323,7 +320,7 @@ void PairMEAM::allocate() void PairMEAM::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -336,12 +333,12 @@ void PairMEAM::coeff(int narg, char **arg) if (!allocated) allocate(); - if (narg < 6) error->all("Incorrect args for pair coefficients"); + if (narg < 6) error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read MEAM element names between 2 filenames // nelements = # of MEAM elements @@ -353,7 +350,7 @@ void PairMEAM::coeff(int narg, char **arg) delete [] mass; } nelements = narg - 4 - atom->ntypes; - if (nelements < 1) error->all("Incorrect args for pair coefficients"); + if (nelements < 1) error->all(FLERR,"Incorrect args for pair coefficients"); elements = new char*[nelements]; mass = new double[nelements]; @@ -379,7 +376,7 @@ void PairMEAM::coeff(int narg, char **arg) if (strcmp(arg[i],elements[j]) == 0) break; if (j < nelements) map[m] = j; else if (strcmp(arg[i],"NULL") == 0) map[m] = -1; - else error->all("Incorrect args for pair coefficients"); + else error->all(FLERR,"Incorrect args for pair coefficients"); } // clear setflag since coeff() called once with I,J = * * @@ -401,7 +398,7 @@ void PairMEAM::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -411,7 +408,7 @@ void PairMEAM::coeff(int narg, char **arg) void PairMEAM::init_style() { if (force->newton_pair == 0) - error->all("Pair style MEAM requires newton pair on"); + error->all(FLERR,"Pair style MEAM requires newton pair on"); // need full and half neighbor list @@ -464,7 +461,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open MEAM potential file %s",globalfile); - error->one(str); + error->one(FLERR,str); } } @@ -544,7 +541,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) } if (nwords != params_per_line) - error->all("Incorrect format in MEAM potential file"); + error->all(FLERR,"Incorrect format in MEAM potential file"); // words = ptrs to all words in line // strip single and double quotes from words @@ -571,7 +568,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) else if (strcmp(words[1],"hcp") == 0) lat[i] = HCP; else if (strcmp(words[1],"dim") == 0) lat[i] = DIM; else if (strcmp(words[1],"dia") == 0) lat[i] = DIAMOND; - else error->all("Unrecognized lattice type in MEAM file 1"); + else error->all(FLERR,"Unrecognized lattice type in MEAM file 1"); // store parameters @@ -599,7 +596,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) // error if didn't find all elements in file if (nset != nelements) - error->all("Did not find all elements in MEAM library file"); + error->all(FLERR,"Did not find all elements in MEAM library file"); // pass element parameters to MEAM package @@ -645,7 +642,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open MEAM potential file %s",userfile); - error->one(str); + error->one(FLERR,str); } } @@ -695,7 +692,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) char str[128]; sprintf(str,"Keyword %s in MEAM parameter file not recognized", params[0]); - error->all(str); + error->all(FLERR,str); } nindex = nparams - 2; for (i = 0; i < nindex; i++) index[i] = atoi(params[i+1]); @@ -712,7 +709,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) else if (strcmp(params[nparams-1],"c11") == 0) value = C11; else if (strcmp(params[nparams-1],"l12") == 0) value = L12; else if (strcmp(params[nparams-1],"b2") == 0) value = B2; - else error->all("Unrecognized lattice type in MEAM file 2"); + else error->all(FLERR,"Unrecognized lattice type in MEAM file 2"); } else value = atof(params[nparams-1]); @@ -723,7 +720,7 @@ void PairMEAM::read_files(char *globalfile, char *userfile) if (errorflag) { char str[128]; sprintf(str,"MEAM library error %d",errorflag); - error->all(str); + error->all(FLERR,str); } } diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp index a0b0fc9708..5dd81580cc 100644 --- a/src/MOLECULE/angle_charmm.cpp +++ b/src/MOLECULE/angle_charmm.cpp @@ -193,7 +193,7 @@ void AngleCharmm::allocate() void AngleCharmm::coeff(int narg, char **arg) { - if (narg != 5) error->all("Incorrect args for angle coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -216,7 +216,7 @@ void AngleCharmm::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp index 771093af6b..6c6fa4fc87 100644 --- a/src/MOLECULE/angle_cosine.cpp +++ b/src/MOLECULE/angle_cosine.cpp @@ -152,7 +152,7 @@ void AngleCosine::allocate() void AngleCosine::coeff(int narg, char **arg) { - if (narg != 2) error->all("Incorrect args for angle coefficients"); + if (narg != 2) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -167,7 +167,7 @@ void AngleCosine::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp index 4d2bd58919..d401c1fffc 100644 --- a/src/MOLECULE/angle_cosine_periodic.cpp +++ b/src/MOLECULE/angle_cosine_periodic.cpp @@ -199,7 +199,7 @@ void AngleCosinePeriodic::allocate() void AngleCosinePeriodic::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for angle coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -208,7 +208,7 @@ void AngleCosinePeriodic::coeff(int narg, char **arg) double c_one = atof(arg[1]); int b_one = atoi(arg[2]); int n_one = atoi(arg[3]); - if (n_one <= 0) error->all("Incorrect args for angle coefficients"); + if (n_one <= 0) error->all(FLERR,"Incorrect args for angle coefficients"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -219,7 +219,7 @@ void AngleCosinePeriodic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp index caaf44db5e..9262700679 100644 --- a/src/MOLECULE/angle_cosine_squared.cpp +++ b/src/MOLECULE/angle_cosine_squared.cpp @@ -164,7 +164,7 @@ void AngleCosineSquared::allocate() void AngleCosineSquared::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for angle coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -183,7 +183,7 @@ void AngleCosineSquared::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp index 20fa892cee..e3def97499 100644 --- a/src/MOLECULE/angle_harmonic.cpp +++ b/src/MOLECULE/angle_harmonic.cpp @@ -164,7 +164,7 @@ void AngleHarmonic::allocate() void AngleHarmonic::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for angle coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -183,7 +183,7 @@ void AngleHarmonic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_hybrid.cpp b/src/MOLECULE/angle_hybrid.cpp index ac3b8a28a6..a71d87da17 100644 --- a/src/MOLECULE/angle_hybrid.cpp +++ b/src/MOLECULE/angle_hybrid.cpp @@ -162,7 +162,7 @@ void AngleHybrid::settings(int narg, char **arg) { int i,m,istyle; - if (narg < 1) error->all("Illegal angle_style command"); + if (narg < 1) error->all(FLERR,"Illegal angle_style command"); // delete old lists, since cannot just change settings @@ -212,11 +212,11 @@ void AngleHybrid::settings(int narg, char **arg) while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) - error->all("Angle style hybrid cannot use same pair style twice"); + error->all(FLERR,"Angle style hybrid cannot use same pair style twice"); if (strcmp(arg[i],"hybrid") == 0) - error->all("Angle style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Angle style hybrid cannot have hybrid as an argument"); if (strcmp(arg[i],"none") == 0) - error->all("Angle style hybrid cannot have none as an argument"); + error->all(FLERR,"Angle style hybrid cannot have none as an argument"); styles[nstyles] = force->new_angle(arg[i]); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); @@ -252,7 +252,7 @@ void AngleHybrid::coeff(int narg, char **arg) if (m == nstyles) { if (strcmp(arg[1],"none") == 0) none = 1; else if (strcmp(arg[1],"skip") == 0) none = skip = 1; - else error->all("Angle coeff for hybrid has invalid style"); + else error->all(FLERR,"Angle coeff for hybrid has invalid style"); } // move 1st arg to 2nd arg @@ -286,7 +286,8 @@ void AngleHybrid::coeff(int narg, char **arg) double AngleHybrid::equilibrium_angle(int i) { - if (map[i] < 0) error->one("Invoked angle equil angle on angle style none"); + if (map[i] < 0) + error->one(FLERR,"Invoked angle equil angle on angle style none"); return styles[map[i]]->equilibrium_angle(i); } @@ -335,7 +336,7 @@ void AngleHybrid::read_restart(FILE *fp) double AngleHybrid::single(int type, int i1, int i2, int i3) { - if (map[type] < 0) error->one("Invoked angle single on angle style none"); + if (map[type] < 0) error->one(FLERR,"Invoked angle single on angle style none"); return styles[map[type]]->single(type,i1,i2,i3); } diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp index c47309c505..4395c20413 100644 --- a/src/MOLECULE/angle_table.cpp +++ b/src/MOLECULE/angle_table.cpp @@ -29,9 +29,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - enum{LINEAR,SPLINE}; #define MAXLINE 1024 @@ -183,14 +180,14 @@ void AngleTable::allocate() void AngleTable::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal angle_style command"); + if (narg != 2) error->all(FLERR,"Illegal angle_style command"); if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE; - else error->all("Unknown table style in angle style table"); + else error->all(FLERR,"Unknown table style in angle style table"); tablength = force->inumeric(arg[1]); - if (tablength < 2) error->all("Illegal number of angle table entries"); + if (tablength < 2) error->all(FLERR,"Illegal number of angle table entries"); // delete old tables, since cannot just change settings @@ -213,7 +210,7 @@ void AngleTable::settings(int narg, char **arg) void AngleTable::coeff(int narg, char **arg) { - if (narg != 3) error->all("Illegal angle_coeff command"); + if (narg != 3) error->all(FLERR,"Illegal angle_coeff command"); if (!allocated) allocate(); int ilo,ihi; @@ -230,13 +227,13 @@ void AngleTable::coeff(int narg, char **arg) // error check on table parameters - if (tb->ninput <= 1) error->one("Invalid angle table length"); + if (tb->ninput <= 1) error->one(FLERR,"Invalid angle table length"); double alo,ahi; alo = tb->afile[0]; ahi = tb->afile[tb->ninput-1]; if (fabs(alo-0.0) > TINY || fabs(ahi-180.0) > TINY) - error->all("Angle table must range from 0 to 180 degrees"); + error->all(FLERR,"Angle table must range from 0 to 180 degrees"); // convert theta from degrees to radians @@ -261,7 +258,7 @@ void AngleTable::coeff(int narg, char **arg) } ntables++; - if (count == 0) error->all("Illegal angle_coeff command"); + if (count == 0) error->all(FLERR,"Illegal angle_coeff command"); } /* ---------------------------------------------------------------------- @@ -372,14 +369,14 @@ void AngleTable::read_table(Table *tb, char *file, char *keyword) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) - error->one("Did not find keyword in table file"); + error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment if (strstr(line,keyword) == line) break; // matching keyword @@ -510,12 +507,12 @@ void AngleTable::param_extract(Table *tb, char *line) word = strtok(NULL," \t\n\r\f"); tb->theta0 = atof(word); } else { - error->one("Invalid keyword in angle table parameters"); + error->one(FLERR,"Invalid keyword in angle table parameters"); } word = strtok(NULL," \t\n\r\f"); } - if (tb->ninput == 0) error->one("Angle table parameters did not set N"); + if (tb->ninput == 0) error->one(FLERR,"Angle table parameters did not set N"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp index 72afefb8d1..46478bac07 100644 --- a/src/MOLECULE/atom_vec_angle.cpp +++ b/src/MOLECULE/atom_vec_angle.cpp @@ -23,9 +23,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELTA 10000 /* ---------------------------------------------------------------------- */ @@ -61,7 +58,7 @@ void AtomVecAngle::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -763,13 +760,13 @@ void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp index fb0a3e0583..700eb275a0 100644 --- a/src/MOLECULE/atom_vec_bond.cpp +++ b/src/MOLECULE/atom_vec_bond.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELTA 10000 /* ---------------------------------------------------------------------- */ @@ -62,7 +59,7 @@ void AtomVecBond::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -723,13 +720,13 @@ void AtomVecBond::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp index 15b3c3a84d..5a14488fdb 100644 --- a/src/MOLECULE/atom_vec_full.cpp +++ b/src/MOLECULE/atom_vec_full.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELTA 10000 /* ---------------------------------------------------------------------- */ @@ -62,7 +59,7 @@ void AtomVecFull::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -926,13 +923,13 @@ void AtomVecFull::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[3]); diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp index 75c7df86cb..1672541b62 100644 --- a/src/MOLECULE/atom_vec_molecular.cpp +++ b/src/MOLECULE/atom_vec_molecular.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELTA 10000 /* ---------------------------------------------------------------------- */ @@ -62,7 +59,7 @@ void AtomVecMolecular::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -909,13 +906,13 @@ void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp index 26a8454dbf..571ace9876 100644 --- a/src/MOLECULE/bond_fene.cpp +++ b/src/MOLECULE/bond_fene.cpp @@ -89,8 +89,8 @@ void BondFENE::compute(int eflag, int vflag) char str[128]; sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g", update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq)); - error->warning(str,0); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); + error->warning(FLERR,str,0); + if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond"); rlogarg = 0.1; } @@ -151,7 +151,7 @@ void BondFENE::allocate() void BondFENE::coeff(int narg, char **arg) { - if (narg != 5) error->all("Incorrect args for bond coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -172,7 +172,7 @@ void BondFENE::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- @@ -186,7 +186,7 @@ void BondFENE::init_style() if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) { if (comm->me == 0) - error->warning("Use special bonds = 0,1,1 with bond style fene"); + error->warning(FLERR,"Use special bonds = 0,1,1 with bond style fene"); } } @@ -246,8 +246,8 @@ double BondFENE::single(int type, double rsq, int i, int j) char str[128]; sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %g", update->ntimestep,sqrt(rsq)); - error->warning(str,0); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); + error->warning(FLERR,str,0); + if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond"); rlogarg = 0.1; } diff --git a/src/MOLECULE/bond_fene_expand.cpp b/src/MOLECULE/bond_fene_expand.cpp index 560179beab..a466ca4dbf 100644 --- a/src/MOLECULE/bond_fene_expand.cpp +++ b/src/MOLECULE/bond_fene_expand.cpp @@ -94,8 +94,8 @@ void BondFENEExpand::compute(int eflag, int vflag) char str[128]; sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g", update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq)); - error->warning(str,0); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); + error->warning(FLERR,str,0); + if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond"); rlogarg = 0.1; } @@ -157,7 +157,7 @@ void BondFENEExpand::allocate() void BondFENEExpand::coeff(int narg, char **arg) { - if (narg != 6) error->all("Incorrect args for bond coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -180,7 +180,7 @@ void BondFENEExpand::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- @@ -194,7 +194,7 @@ void BondFENEExpand::init_style() if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) { if (comm->me == 0) - error->warning("Use special bonds = 0,1,1 with bond style fene/expand"); + error->warning(FLERR,"Use special bonds = 0,1,1 with bond style fene/expand"); } } @@ -260,8 +260,8 @@ double BondFENEExpand::single(int type, double rsq, int i, int j) char str[128]; sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %g", update->ntimestep,sqrt(rsq)); - error->warning(str,0); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); + error->warning(FLERR,str,0); + if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond"); rlogarg = 0.1; } diff --git a/src/MOLECULE/bond_harmonic.cpp b/src/MOLECULE/bond_harmonic.cpp index 9e4c2756a2..63af84bf98 100644 --- a/src/MOLECULE/bond_harmonic.cpp +++ b/src/MOLECULE/bond_harmonic.cpp @@ -118,7 +118,7 @@ void BondHarmonic::allocate() void BondHarmonic::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for bond coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -135,7 +135,7 @@ void BondHarmonic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/bond_morse.cpp b/src/MOLECULE/bond_morse.cpp index cd3fe47c93..135c6f8df5 100644 --- a/src/MOLECULE/bond_morse.cpp +++ b/src/MOLECULE/bond_morse.cpp @@ -123,7 +123,7 @@ void BondMorse::allocate() void BondMorse::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for bond coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -142,7 +142,7 @@ void BondMorse::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/bond_nonlinear.cpp b/src/MOLECULE/bond_nonlinear.cpp index a848cce902..1a31b4c4b1 100644 --- a/src/MOLECULE/bond_nonlinear.cpp +++ b/src/MOLECULE/bond_nonlinear.cpp @@ -120,7 +120,7 @@ void BondNonlinear::allocate() void BondNonlinear::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for bond coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -139,7 +139,7 @@ void BondNonlinear::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/bond_quartic.cpp b/src/MOLECULE/bond_quartic.cpp index f9e5bd8600..c8fc882d57 100755 --- a/src/MOLECULE/bond_quartic.cpp +++ b/src/MOLECULE/bond_quartic.cpp @@ -200,7 +200,7 @@ void BondQuartic::allocate() void BondQuartic::coeff(int narg, char **arg) { - if (narg != 6) error->all("Incorrect args for bond coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -223,7 +223,7 @@ void BondQuartic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- @@ -233,19 +233,19 @@ void BondQuartic::coeff(int narg, char **arg) void BondQuartic::init_style() { if (force->pair == NULL || force->pair->single_enable == 0) - error->all("Pair style does not support bond_style quartic"); + error->all(FLERR,"Pair style does not support bond_style quartic"); if (force->angle) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); + error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions"); if (force->dihedral) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); + error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions"); if (force->improper) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); + error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions"); // special bonds must be 1 1 1 if (force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) - error->all("Bond style quartic requires special_bonds = 1,1,1"); + error->all(FLERR,"Bond style quartic requires special_bonds = 1,1,1"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/bond_table.cpp b/src/MOLECULE/bond_table.cpp index 1e6abb88a8..04743097e6 100644 --- a/src/MOLECULE/bond_table.cpp +++ b/src/MOLECULE/bond_table.cpp @@ -33,9 +33,6 @@ enum{LINEAR,SPLINE}; #define MAXLINE 1024 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ BondTable::BondTable(LAMMPS *lmp) : Bond(lmp) @@ -135,14 +132,14 @@ void BondTable::allocate() void BondTable::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal bond_style command"); + if (narg != 2) error->all(FLERR,"Illegal bond_style command"); if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE; - else error->all("Unknown table style in bond style table"); + else error->all(FLERR,"Unknown table style in bond style table"); tablength = force->inumeric(arg[1]); - if (tablength < 2) error->all("Illegal number of bond table entries"); + if (tablength < 2) error->all(FLERR,"Illegal number of bond table entries"); // delete old tables, since cannot just change settings @@ -165,7 +162,7 @@ void BondTable::settings(int narg, char **arg) void BondTable::coeff(int narg, char **arg) { - if (narg != 3) error->all("Illegal bond_coeff command"); + if (narg != 3) error->all(FLERR,"Illegal bond_coeff command"); if (!allocated) allocate(); int ilo,ihi; @@ -182,11 +179,11 @@ void BondTable::coeff(int narg, char **arg) // error check on table parameters - if (tb->ninput <= 1) error->one("Invalid bond table length"); + if (tb->ninput <= 1) error->one(FLERR,"Invalid bond table length"); tb->lo = tb->rfile[0]; tb->hi = tb->rfile[tb->ninput-1]; - if (tb->lo >= tb->hi) error->all("Bond table values are not increasing"); + if (tb->lo >= tb->hi) error->all(FLERR,"Bond table values are not increasing"); // spline read-in and compute r,e,f vectors within table @@ -204,7 +201,7 @@ void BondTable::coeff(int narg, char **arg) } ntables++; - if (count == 0) error->all("Illegal bond_coeff command"); + if (count == 0) error->all(FLERR,"Illegal bond_coeff command"); } /* ---------------------------------------------------------------------- @@ -296,14 +293,14 @@ void BondTable::read_table(Table *tb, char *file, char *keyword) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) - error->one("Did not find keyword in table file"); + error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment if (strstr(line,keyword) == line) break; // matching keyword @@ -433,12 +430,12 @@ void BondTable::param_extract(Table *tb, char *line) word = strtok(NULL," \t\n\r\f"); tb->r0 = atof(word); } else { - error->one("Invalid keyword in bond table parameters"); + error->one(FLERR,"Invalid keyword in bond table parameters"); } word = strtok(NULL," \t\n\r\f"); } - if (tb->ninput == 0) error->one("Bond table parameters did not set N"); + if (tb->ninput == 0) error->one(FLERR,"Bond table parameters did not set N"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index 5d29cab633..a404311150 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -151,7 +151,7 @@ void DihedralCharmm::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -324,7 +324,7 @@ void DihedralCharmm::allocate() void DihedralCharmm::coeff(int narg, char **arg) { - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -340,9 +340,9 @@ void DihedralCharmm::coeff(int narg, char **arg) double weight_one = force->numeric(arg[4]); if (multiplicity_one < 0) - error->all("Incorrect multiplicity arg for dihedral coefficients"); + error->all(FLERR,"Incorrect multiplicity arg for dihedral coefficients"); if (weight_one < 0.0 || weight_one > 1.0) - error->all("Incorrect weight arg for dihedral coefficients"); + error->all(FLERR,"Incorrect weight arg for dihedral coefficients"); double PI = 4.0*atan(1.0); @@ -358,7 +358,7 @@ void DihedralCharmm::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- @@ -377,14 +377,14 @@ void DihedralCharmm::init_style() if (weightflag) { int itmp; if (force->pair == NULL) - error->all("Dihedral charmm is incompatible with Pair style"); + error->all(FLERR,"Dihedral charmm is incompatible with Pair style"); lj14_1 = (double **) force->pair->extract("lj14_1",itmp); lj14_2 = (double **) force->pair->extract("lj14_2",itmp); lj14_3 = (double **) force->pair->extract("lj14_3",itmp); lj14_4 = (double **) force->pair->extract("lj14_4",itmp); int *ptr = (int *) force->pair->extract("implicit",itmp); if (!lj14_1 || !lj14_2 || !lj14_3 || !lj14_4 || !ptr) - error->all("Dihedral charmm is incompatible with Pair style"); + error->all(FLERR,"Dihedral charmm is incompatible with Pair style"); implicit = *ptr; } } diff --git a/src/MOLECULE/dihedral_harmonic.cpp b/src/MOLECULE/dihedral_harmonic.cpp index cefd57d42e..b88584d16a 100644 --- a/src/MOLECULE/dihedral_harmonic.cpp +++ b/src/MOLECULE/dihedral_harmonic.cpp @@ -141,7 +141,7 @@ void DihedralHarmonic::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -272,7 +272,7 @@ void DihedralHarmonic::allocate() void DihedralHarmonic::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for dihedral coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -287,9 +287,9 @@ void DihedralHarmonic::coeff(int narg, char **arg) // backwards compatibility and is probably not needed if (sign_one != -1 && sign_one != 1) - error->all("Incorrect sign arg for dihedral coefficients"); + error->all(FLERR,"Incorrect sign arg for dihedral coefficients"); if (multiplicity_one < 0) - error->all("Incorrect multiplicity arg for dihedral coefficients"); + error->all(FLERR,"Incorrect multiplicity arg for dihedral coefficients"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -307,7 +307,7 @@ void DihedralHarmonic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp index 639520e8a8..7a50eb4fc0 100644 --- a/src/MOLECULE/dihedral_helix.cpp +++ b/src/MOLECULE/dihedral_helix.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define TOLERANCE 0.05 #define SMALL 0.001 #define SMALLER 0.00001 @@ -173,7 +170,7 @@ void DihedralHelix::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -284,7 +281,7 @@ void DihedralHelix::allocate() void DihedralHelix::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for dihedral coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -303,7 +300,7 @@ void DihedralHelix::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/dihedral_hybrid.cpp b/src/MOLECULE/dihedral_hybrid.cpp index 2d17ea028a..4b416281d8 100644 --- a/src/MOLECULE/dihedral_hybrid.cpp +++ b/src/MOLECULE/dihedral_hybrid.cpp @@ -168,12 +168,12 @@ void DihedralHybrid::settings(int narg, char **arg) for (int m = 0; m < nstyles; m++) { for (int i = 0; i < m; i++) if (strcmp(arg[m],arg[i]) == 0) - error->all("Dihedral style hybrid cannot use " + error->all(FLERR,"Dihedral style hybrid cannot use " "same dihedral style twice"); if (strcmp(arg[m],"hybrid") == 0) - error->all("Dihedral style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Dihedral style hybrid cannot have hybrid as an argument"); if (strcmp(arg[m],"none") == 0) - error->all("Dihedral style hybrid cannot have none as an argument"); + error->all(FLERR,"Dihedral style hybrid cannot have none as an argument"); styles[m] = force->new_dihedral(arg[m]); keywords[m] = new char[strlen(arg[m])+1]; strcpy(keywords[m],arg[m]); @@ -203,7 +203,7 @@ void DihedralHybrid::coeff(int narg, char **arg) if (m == nstyles) { if (strcmp(arg[1],"none") == 0) none = 1; else if (strcmp(arg[1],"skip") == 0) none = skip = 1; - else error->all("Dihedral coeff for hybrid has invalid style"); + else error->all(FLERR,"Dihedral coeff for hybrid has invalid style"); } // move 1st arg to 2nd arg diff --git a/src/MOLECULE/dihedral_multi_harmonic.cpp b/src/MOLECULE/dihedral_multi_harmonic.cpp index 291cea35e9..ea0fd5532e 100644 --- a/src/MOLECULE/dihedral_multi_harmonic.cpp +++ b/src/MOLECULE/dihedral_multi_harmonic.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define TOLERANCE 0.05 #define SMALL 0.001 @@ -166,7 +163,7 @@ void DihedralMultiHarmonic::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -275,7 +272,7 @@ void DihedralMultiHarmonic::allocate() void DihedralMultiHarmonic::coeff(int narg, char **arg) { - if (narg != 6) error->all("Incorrect args for dihedral coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -298,7 +295,7 @@ void DihedralMultiHarmonic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/dihedral_opls.cpp b/src/MOLECULE/dihedral_opls.cpp index 99bdd993ec..4f4fd75882 100644 --- a/src/MOLECULE/dihedral_opls.cpp +++ b/src/MOLECULE/dihedral_opls.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define TOLERANCE 0.05 #define SMALL 0.001 #define SMALLER 0.00001 @@ -172,7 +169,7 @@ void DihedralOPLS::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -288,7 +285,7 @@ void DihedralOPLS::allocate() void DihedralOPLS::coeff(int narg, char **arg) { - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); + if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -311,7 +308,7 @@ void DihedralOPLS::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/improper_cvff.cpp b/src/MOLECULE/improper_cvff.cpp index 2ea0b97f56..401bcad85a 100644 --- a/src/MOLECULE/improper_cvff.cpp +++ b/src/MOLECULE/improper_cvff.cpp @@ -156,7 +156,7 @@ void ImproperCvff::compute(int eflag, int vflag) "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -295,7 +295,7 @@ void ImproperCvff::allocate() void ImproperCvff::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for improper coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for improper coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -314,7 +314,7 @@ void ImproperCvff::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for improper coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp index 7e7db4d03f..62d5cd54b6 100644 --- a/src/MOLECULE/improper_harmonic.cpp +++ b/src/MOLECULE/improper_harmonic.cpp @@ -127,7 +127,7 @@ void ImproperHarmonic::compute(int eflag, int vflag) "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -234,7 +234,7 @@ void ImproperHarmonic::allocate() void ImproperHarmonic::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for improper coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for improper coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -253,7 +253,7 @@ void ImproperHarmonic::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for improper coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/improper_hybrid.cpp b/src/MOLECULE/improper_hybrid.cpp index 767c12b936..645913e841 100644 --- a/src/MOLECULE/improper_hybrid.cpp +++ b/src/MOLECULE/improper_hybrid.cpp @@ -168,11 +168,11 @@ void ImproperHybrid::settings(int narg, char **arg) for (int m = 0; m < nstyles; m++) { for (int i = 0; i < m; i++) if (strcmp(arg[m],arg[i]) == 0) - error->all("Improper style hybrid cannot use same improper style twice"); + error->all(FLERR,"Improper style hybrid cannot use same improper style twice"); if (strcmp(arg[m],"hybrid") == 0) - error->all("Improper style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Improper style hybrid cannot have hybrid as an argument"); if (strcmp(arg[m],"none") == 0) - error->all("Improper style hybrid cannot have none as an argument"); + error->all(FLERR,"Improper style hybrid cannot have none as an argument"); styles[m] = force->new_improper(arg[m]); keywords[m] = new char[strlen(arg[m])+1]; strcpy(keywords[m],arg[m]); @@ -200,7 +200,7 @@ void ImproperHybrid::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[1],"none") == 0) none = 1; - else error->all("Improper coeff for hybrid has invalid style"); + else error->all(FLERR,"Improper coeff for hybrid has invalid style"); } // move 1st arg to 2nd arg diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp index 97cc1f65ad..34fddf708a 100644 --- a/src/MOLECULE/improper_umbrella.cpp +++ b/src/MOLECULE/improper_umbrella.cpp @@ -133,7 +133,7 @@ void ImproperUmbrella::compute(int eflag, int vflag) "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -255,7 +255,7 @@ void ImproperUmbrella::allocate() void ImproperUmbrella::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for improper coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for improper coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -276,7 +276,7 @@ void ImproperUmbrella::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for improper coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index 243e837219..cb5429b3f4 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define SMALL 0.001 #define CHUNK 8 @@ -276,7 +273,7 @@ void PairHbondDreidingLJ::allocate() void PairHbondDreidingLJ::settings(int narg, char **arg) { - if (narg != 4) error->all("Illegal pair_style command"); + if (narg != 4) error->all(FLERR,"Illegal pair_style command"); ap_global = force->inumeric(arg[0]); cut_inner_global = force->numeric(arg[1]); @@ -291,7 +288,7 @@ void PairHbondDreidingLJ::settings(int narg, char **arg) void PairHbondDreidingLJ::coeff(int narg, char **arg) { if (narg < 6 || narg > 9) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi,klo,khi; @@ -302,7 +299,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg) int donor_flag; if (strcmp(arg[3],"i") == 0) donor_flag = 0; else if (strcmp(arg[3],"j") == 0) donor_flag = 1; - else error->all("Incorrect args for pair coefficients"); + else error->all(FLERR,"Incorrect args for pair coefficients"); double epsilon_one = force->numeric(arg[4]); double sigma_one = force->numeric(arg[5]); @@ -316,7 +313,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg) cut_outer_one = force->numeric(arg[8]); } if (cut_inner_one>cut_outer_one) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; if (narg == 10) cut_angle_one = force->numeric(arg[9]) * PI/180.0; // grow params array if necessary @@ -352,7 +349,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg) } nparams++; - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -367,14 +364,14 @@ void PairHbondDreidingLJ::init_style() // and computing forces on A,H which may be on different procs if (atom->molecular == 0) - error->all("Pair style hbond/dreiding requires molecular system"); + error->all(FLERR,"Pair style hbond/dreiding requires molecular system"); if (atom->tag_enable == 0) - error->all("Pair style hbond/dreiding requires atom IDs"); + error->all(FLERR,"Pair style hbond/dreiding requires atom IDs"); if (atom->map_style == 0) - error->all("Pair style hbond/dreiding requires an atom map, " + error->all(FLERR,"Pair style hbond/dreiding requires an atom map, " "see atom_modify"); if (force->newton_pair == 0) - error->all("Pair style hbond/dreiding requires newton pair on"); + error->all(FLERR,"Pair style hbond/dreiding requires newton pair on"); // set donor[M]/acceptor[M] if any atom of type M is a donor/acceptor @@ -390,7 +387,7 @@ void PairHbondDreidingLJ::init_style() acceptor[j] = 1; } - if (!anyflag) error->all("No pair hbond/dreiding coefficients set"); + if (!anyflag) error->all(FLERR,"No pair hbond/dreiding coefficients set"); // set additional param values // offset is for LJ only, angle term is not included diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp index 62f75f0a18..2e70d928d1 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define SMALL 0.001 #define CHUNK 8 @@ -216,7 +213,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) void PairHbondDreidingMorse::coeff(int narg, char **arg) { if (narg < 8 || narg > 11) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi,klo,khi; @@ -227,7 +224,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg) int donor_flag; if (strcmp(arg[3],"i") == 0) donor_flag = 0; else if (strcmp(arg[3],"j") == 0) donor_flag = 1; - else error->all("Incorrect args for pair coefficients"); + else error->all(FLERR,"Incorrect args for pair coefficients"); double d0_one = force->numeric(arg[4]); double alpha_one = force->numeric(arg[5]); @@ -242,7 +239,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg) cut_outer_one = force->numeric(arg[9]); } if (cut_inner_one>cut_outer_one) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; if (narg > 10) cut_angle_one = force->numeric(arg[10]) * PI/180.0; @@ -280,7 +277,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg) } nparams++; - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -295,14 +292,14 @@ void PairHbondDreidingMorse::init_style() // and computing forces on A,H which may be on different procs if (atom->molecular == 0) - error->all("Pair style hbond/dreiding requires molecular system"); + error->all(FLERR,"Pair style hbond/dreiding requires molecular system"); if (atom->tag_enable == 0) - error->all("Pair style hbond/dreiding requires atom IDs"); + error->all(FLERR,"Pair style hbond/dreiding requires atom IDs"); if (atom->map_style == 0) - error->all("Pair style hbond/dreiding requires an atom map, " + error->all(FLERR,"Pair style hbond/dreiding requires an atom map, " "see atom_modify"); if (force->newton_pair == 0) - error->all("Pair style hbond/dreiding requires newton pair on"); + error->all(FLERR,"Pair style hbond/dreiding requires newton pair on"); // set donor[M]/acceptor[M] if any atom of type M is a donor/acceptor @@ -318,7 +315,7 @@ void PairHbondDreidingMorse::init_style() acceptor[j] = 1; } - if (!anyflag) error->all("No pair hbond/dreiding coefficients set"); + if (!anyflag) error->all(FLERR,"No pair hbond/dreiding coefficients set"); // set additional param values // offset is for Morse only, angle term is not included diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp index 3552f9e18b..875f4c95a2 100644 --- a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp +++ b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // same as in pair.cpp -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCharmmCoulCharmm::PairLJCharmmCoulCharmm(LAMMPS *lmp) : Pair(lmp) @@ -227,7 +224,7 @@ void PairLJCharmmCoulCharmm::allocate() void PairLJCharmmCoulCharmm::settings(int narg, char **arg) { if (narg != 2 && narg != 4) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); cut_lj_inner = force->numeric(arg[0]); cut_lj = force->numeric(arg[1]); @@ -247,7 +244,7 @@ void PairLJCharmmCoulCharmm::settings(int narg, char **arg) void PairLJCharmmCoulCharmm::coeff(int narg, char **arg) { if (narg != 4 && narg != 6) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -275,7 +272,7 @@ void PairLJCharmmCoulCharmm::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -285,14 +282,14 @@ void PairLJCharmmCoulCharmm::coeff(int narg, char **arg) void PairLJCharmmCoulCharmm::init_style() { if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/charmm requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/charmm requires atom attribute q"); neighbor->request(this); // require cut_lj_inner < cut_lj, cut_coul_inner < cut_coul if (cut_lj_inner >= cut_lj || cut_coul_inner >= cut_coul) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; diff --git a/src/Makefile b/src/Makefile index c95e423ba6..c0a9df822a 100755 --- a/src/Makefile +++ b/src/Makefile @@ -156,6 +156,10 @@ no-user: @for p in $(PACKUSER); do $(MAKE) no-$$p; done yes-%: + @if [ ! -e Makefile.package ]; \ + then cp Makefile.package.empty Makefile.package; fi + @if [ ! -e Makefile.package.settings ]; \ + then cp Makefile.package.settings.empty Makefile.package.settings; fi @if [ ! -e $(YESDIR) ]; then \ echo "Package $(@:yes-%=%) does not exist"; \ else \ diff --git a/src/OPT/pair_eam_opt.cpp b/src/OPT/pair_eam_opt.cpp index 83a9580b92..616234b69b 100644 --- a/src/OPT/pair_eam_opt.cpp +++ b/src/OPT/pair_eam_opt.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairEAMOpt::PairEAMOpt(LAMMPS *lmp) : PairEAM(lmp) {} diff --git a/src/OPT/pair_lj_charmm_coul_long_opt.cpp b/src/OPT/pair_lj_charmm_coul_long_opt.cpp index 6049eb2a31..49519d4761 100644 --- a/src/OPT/pair_lj_charmm_coul_long_opt.cpp +++ b/src/OPT/pair_lj_charmm_coul_long_opt.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define EWALD_A1 0.254829592 diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp index 95a72d10fd..b571400621 100644 --- a/src/PERI/atom_vec_peri.cpp +++ b/src/PERI/atom_vec_peri.cpp @@ -64,7 +64,7 @@ void AtomVecPeri::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -761,15 +761,15 @@ void AtomVecPeri::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); vfrac[nlocal] = atof(values[2]); rmass[nlocal] = atof(values[3]); - if (rmass[nlocal] <= 0.0) error->one("Invalid mass value"); + if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid mass value"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; @@ -800,7 +800,7 @@ int AtomVecPeri::data_atom_hybrid(int nlocal, char **values) { vfrac[nlocal] = atof(values[0]); rmass[nlocal] = atof(values[1]); - if (rmass[nlocal] <= 0.0) error->one("Invalid mass value"); + if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid mass value"); s0[nlocal] = DBL_MAX; x0[nlocal][0] = x[nlocal][0]; diff --git a/src/PERI/compute_damage_atom.cpp b/src/PERI/compute_damage_atom.cpp index a66e305983..92407985c8 100644 --- a/src/PERI/compute_damage_atom.cpp +++ b/src/PERI/compute_damage_atom.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; ComputeDamageAtom::ComputeDamageAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute damage/atom command"); + if (narg != 3) error->all(FLERR,"Illegal compute damage/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -58,7 +58,7 @@ void ComputeDamageAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"damage/peri") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute damage/atom"); + error->warning(FLERR,"More than one compute damage/atom"); // find associated PERI_NEIGH fix that must exist @@ -66,7 +66,7 @@ void ComputeDamageAtom::init() for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"PERI_NEIGH") == 0) ifix_peri = i; if (ifix_peri == -1) - error->all("Compute damage/atom requires peridynamic potential"); + error->all(FLERR,"Compute damage/atom requires peridynamic potential"); } /* ---------------------------------------------------------------------- */ diff --git a/src/PERI/fix_peri_neigh.cpp b/src/PERI/fix_peri_neigh.cpp index 666a276973..a6dbbcdfe5 100644 --- a/src/PERI/fix_peri_neigh.cpp +++ b/src/PERI/fix_peri_neigh.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixPeriNeigh::FixPeriNeigh(LAMMPS *lmp,int narg, char **arg) : @@ -251,7 +248,7 @@ void FixPeriNeigh::setup(int vflag) for (jj = 0; jj < jnum; jj++) { for (int kk = jj+1; kk < jnum; kk++) { if (partner[i][jj] == partner[i][kk]) - error->one("Duplicate particle in PeriDynamic bond - " + error->one(FLERR,"Duplicate particle in PeriDynamic bond - " "simulation box is too small"); } } diff --git a/src/PERI/pair_peri_lps.cpp b/src/PERI/pair_peri_lps.cpp index ec50bdf0ec..4efd0b4f31 100644 --- a/src/PERI/pair_peri_lps.cpp +++ b/src/PERI/pair_peri_lps.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairPeriLPS::PairPeriLPS(LAMMPS *lmp) : Pair(lmp) @@ -359,7 +356,7 @@ void PairPeriLPS::allocate() void PairPeriLPS::settings(int narg, char **arg) { - if (narg) error->all("Illegal pair_style command"); + if (narg) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -368,7 +365,7 @@ void PairPeriLPS::settings(int narg, char **arg) void PairPeriLPS::coeff(int narg, char **arg) { - if (narg != 7) error->all("Incorrect args for pair coefficients"); + if (narg != 7) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -394,7 +391,7 @@ void PairPeriLPS::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -403,7 +400,7 @@ void PairPeriLPS::coeff(int narg, char **arg) double PairPeriLPS::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); bulkmodulus[j][i] = bulkmodulus[i][j]; shearmodulus[j][i] = shearmodulus[i][j]; @@ -421,16 +418,16 @@ void PairPeriLPS::init_style() { // error checks - if (!atom->peri_flag) error->all("Pair style peri requires atom style peri"); + if (!atom->peri_flag) error->all(FLERR,"Pair style peri requires atom style peri"); if (atom->map_style == 0) - error->all("Pair peri requires an atom map, see atom_modify"); + error->all(FLERR,"Pair peri requires an atom map, see atom_modify"); if (domain->lattice == NULL) - error->all("Pair peri requires a lattice be defined"); + error->all(FLERR,"Pair peri requires a lattice be defined"); if (domain->lattice->xlattice != domain->lattice->ylattice || domain->lattice->xlattice != domain->lattice->zlattice || domain->lattice->ylattice != domain->lattice->zlattice) - error->all("Pair peri lattice is not identical in x, y, and z"); + error->all(FLERR,"Pair peri lattice is not identical in x, y, and z"); // if first init, create Fix needed for storing fixed neighbors @@ -448,7 +445,7 @@ void PairPeriLPS::init_style() for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"PERI_NEIGH") == 0) ifix_peri = i; - if (ifix_peri == -1) error->all("Fix peri neigh does not exist"); + if (ifix_peri == -1) error->all(FLERR,"Fix peri neigh does not exist"); neighbor->request(this); } @@ -620,7 +617,7 @@ double PairPeriLPS::influence_function(double xi_x, double xi_y, double xi_z) double omega; if (fabs(r) < 2.2204e-016) - error->one("Divide by 0 in influence function of pair peri/lps"); + error->one(FLERR,"Divide by 0 in influence function of pair peri/lps"); omega = 1.0/r; return omega; } diff --git a/src/PERI/pair_peri_pmb.cpp b/src/PERI/pair_peri_pmb.cpp index 436745e938..c989de6afd 100644 --- a/src/PERI/pair_peri_pmb.cpp +++ b/src/PERI/pair_peri_pmb.cpp @@ -37,9 +37,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairPeriPMB::PairPeriPMB(LAMMPS *lmp) : Pair(lmp) @@ -301,7 +298,7 @@ void PairPeriPMB::allocate() void PairPeriPMB::settings(int narg, char **arg) { - if (narg) error->all("Illegal pair_style command"); + if (narg) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -310,7 +307,7 @@ void PairPeriPMB::settings(int narg, char **arg) void PairPeriPMB::coeff(int narg, char **arg) { - if (narg != 6) error->all("Incorrect args for pair coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -334,7 +331,7 @@ void PairPeriPMB::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -343,7 +340,7 @@ void PairPeriPMB::coeff(int narg, char **arg) double PairPeriPMB::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); kspring[j][i] = kspring[i][j]; alpha[j][i] = alpha[i][j]; @@ -360,16 +357,16 @@ void PairPeriPMB::init_style() { // error checks - if (!atom->peri_flag) error->all("Pair style peri requires atom style peri"); + if (!atom->peri_flag) error->all(FLERR,"Pair style peri requires atom style peri"); if (atom->map_style == 0) - error->all("Pair peri requires an atom map, see atom_modify"); + error->all(FLERR,"Pair peri requires an atom map, see atom_modify"); if (domain->lattice == NULL) - error->all("Pair peri requires a lattice be defined"); + error->all(FLERR,"Pair peri requires a lattice be defined"); if (domain->lattice->xlattice != domain->lattice->ylattice || domain->lattice->xlattice != domain->lattice->zlattice || domain->lattice->ylattice != domain->lattice->zlattice) - error->all("Pair peri lattice is not identical in x, y, and z"); + error->all(FLERR,"Pair peri lattice is not identical in x, y, and z"); // if first init, create Fix needed for storing fixed neighbors @@ -387,7 +384,7 @@ void PairPeriPMB::init_style() for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"PERI_NEIGH") == 0) ifix_peri = i; - if (ifix_peri == -1) error->all("Fix peri neigh does not exist"); + if (ifix_peri == -1) error->all(FLERR,"Fix peri neigh does not exist"); neighbor->request(this); } diff --git a/src/POEMS/fix_poems.cpp b/src/POEMS/fix_poems.cpp index 47b82dfa28..4e50abb4f6 100644 --- a/src/POEMS/fix_poems.cpp +++ b/src/POEMS/fix_poems.cpp @@ -44,9 +44,6 @@ using namespace LAMMPS_NS; #define EPSILON 1.0e-7 #define MAXJACOBI 50 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- define rigid bodies and joints, initiate POEMS ------------------------------------------------------------------------- */ @@ -91,19 +88,19 @@ FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) : // set natom2body, atom2body for all atoms and nbody = # of rigid bodies // atoms must also be in fix group to be in a body - if (narg < 4) error->all("Illegal fix poems command"); + if (narg < 4) error->all(FLERR,"Illegal fix poems command"); // group = arg has list of groups if (strcmp(arg[3],"group") == 0) { nbody = narg-4; - if (nbody <= 0) error->all("Illegal fix poems command"); + if (nbody <= 0) error->all(FLERR,"Illegal fix poems command"); int *igroups = new int[nbody]; for (ibody = 0; ibody < nbody; ibody++) { igroups[ibody] = group->find(arg[ibody+4]); if (igroups[ibody] == -1) - error->all("Could not find fix poems group ID"); + error->all(FLERR,"Could not find fix poems group ID"); } int *mask = atom->mask; @@ -138,9 +135,9 @@ FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) : // use nall as incremented ptr to set atom2body[] values for each atom } else if (strcmp(arg[3],"molecule") == 0) { - if (narg != 4) error->all("Illegal fix poems command"); + if (narg != 4) error->all(FLERR,"Illegal fix poems command"); if (atom->molecular == 0) - error->all("Must use a molecular atom style with fix poems molecule"); + error->all(FLERR,"Must use a molecular atom style with fix poems molecule"); int *mask = atom->mask; int *molecule = atom->molecule; @@ -179,19 +176,19 @@ FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) : delete [] ncount; delete [] nall; - } else error->all("Illegal fix poems command"); + } else error->all(FLERR,"Illegal fix poems command"); // error if no bodies // error if any atom in too many bodies - if (nbody == 0) error->all("No rigid bodies defined"); + if (nbody == 0) error->all(FLERR,"No rigid bodies defined"); int flag = 0; for (int i = 0; i < nlocal; i++) if (natom2body[i] > MAXBODY) flag = 1; int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - if (flagall) error->all("Atom in too many rigid bodies - boost MAXBODY"); + if (flagall) error->all(FLERR,"Atom in too many rigid bodies - boost MAXBODY"); // create all nbody-length arrays @@ -226,7 +223,7 @@ FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) : delete [] ncount; for (ibody = 0; ibody < nbody; ibody++) - if (nrigid[ibody] <= 1) error->all("One or zero atoms in rigid body"); + if (nrigid[ibody] <= 1) error->all(FLERR,"One or zero atoms in rigid body"); // build list of joint connections and check for cycles and trees @@ -331,7 +328,7 @@ void FixPOEMS::init() int count = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"poems") == 0) count++; - if (count > 1 && comm->me == 0) error->warning("More than one fix poems"); + if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one fix poems"); // error if npt,nph fix comes before rigid fix @@ -342,7 +339,7 @@ void FixPOEMS::init() if (i < modify->nfix) { for (int j = i; j < modify->nfix; j++) if (strcmp(modify->fix[j]->style,"poems") == 0) - error->all("POEMS fix must come before NPT/NPH fix"); + error->all(FLERR,"POEMS fix must come before NPT/NPH fix"); } // timestep info @@ -456,7 +453,7 @@ void FixPOEMS::init() tensor[0][2] = tensor[2][0] = all[ibody][5]; ierror = jacobi(tensor,inertia[ibody],evectors); - if (ierror) error->all("Insufficient Jacobi rotations for POEMS body"); + if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for POEMS body"); ex_space[ibody][0] = evectors[0][0]; ex_space[ibody][1] = evectors[1][0]; @@ -480,7 +477,7 @@ void FixPOEMS::init() if (inertia[ibody][0] < EPSILON*max || inertia[ibody][1] < EPSILON*max || inertia[ibody][2] < EPSILON*max) - error->all("Rigid body has degenerate moment of inertia"); + error->all(FLERR,"Rigid body has degenerate moment of inertia"); // enforce 3 evectors as a right-handed coordinate system // flip 3rd evector if needed @@ -576,11 +573,11 @@ void FixPOEMS::init() if (fabs(all[ibody][0]-inertia[ibody][0]) > TOLERANCE || fabs(all[ibody][1]-inertia[ibody][1]) > TOLERANCE || fabs(all[ibody][2]-inertia[ibody][2]) > TOLERANCE) - error->all("Bad principal moments"); + error->all(FLERR,"Bad principal moments"); if (fabs(all[ibody][3]) > TOLERANCE || fabs(all[ibody][4]) > TOLERANCE || fabs(all[ibody][5]) > TOLERANCE) - error->all("Bad principal moments"); + error->all(FLERR,"Bad principal moments"); } } @@ -888,7 +885,7 @@ void FixPOEMS::readfile(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix poems file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -1020,7 +1017,7 @@ void FixPOEMS::jointbuild() // warning if no joints if (njoint == 0 && me == 0) - error->warning("No joints between rigid bodies, use fix rigid instead"); + error->warning(FLERR,"No joints between rigid bodies, use fix rigid instead"); // sort joint list in ascending order by body indices // check for loops in joint connections between rigid bodies @@ -1029,7 +1026,7 @@ void FixPOEMS::jointbuild() sortlist(njoint,jlist); if (loopcheck(nbody,njoint,jlist)) - error->all("Cyclic loop in joint connections"); + error->all(FLERR,"Cyclic loop in joint connections"); int *bodyflag = new int[nbody]; for (i = 0; i < nbody; i++) bodyflag[i] = 0; @@ -1038,7 +1035,7 @@ void FixPOEMS::jointbuild() bodyflag[jlist[i][1]]++; } for (i = 0; i < nbody; i++) - if (bodyflag[i] > 2) error->all("Tree structure in joint connections"); + if (bodyflag[i] > 2) error->all(FLERR,"Tree structure in joint connections"); delete [] bodyflag; // allocate and setup joint arrays diff --git a/src/REAX/fix_reax_bonds.cpp b/src/REAX/fix_reax_bonds.cpp index 67317bd6dc..ddd5b5eaa3 100644 --- a/src/REAX/fix_reax_bonds.cpp +++ b/src/REAX/fix_reax_bonds.cpp @@ -37,19 +37,19 @@ using namespace LAMMPS_NS; FixReaxBonds::FixReaxBonds(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix reax/bonds command"); + if (narg < 5) error->all(FLERR,"Illegal fix reax/bonds command"); MPI_Comm_rank(world,&me); nevery = atoi(arg[3]); - if (nevery < 1) error->all("Illegal fix reax/bonds command"); + if (nevery < 1) error->all(FLERR,"Illegal fix reax/bonds command"); if (me == 0) { fp = fopen(arg[4],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix reax/bonds file %s",arg[4]); - error->one(str); + error->one(FLERR,str); } } } @@ -86,7 +86,7 @@ void FixReaxBonds::init() // insure ReaxFF is defined if (force->pair_match("reax",1) == NULL) - error->all("Cannot use fix reax/bonds without pair_style reax"); + error->all(FLERR,"Cannot use fix reax/bonds without pair_style reax"); } /* ---------------------------------------------------------------------- */ @@ -195,7 +195,7 @@ void FixReaxBonds::OutputReaxBonds(bigint ntimestep, FILE *fp) if (numbonds > nsbmax_most) { char str[128]; sprintf(str,"Fix reax/bonds numbonds > nsbmax_most"); - error->one(str); + error->one(FLERR,str); } // print connection table diff --git a/src/REAX/pair_reax.cpp b/src/REAX/pair_reax.cpp index 6e9e3020f0..f32281f5f6 100644 --- a/src/REAX/pair_reax.cpp +++ b/src/REAX/pair_reax.cpp @@ -39,8 +39,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define SMALL 0.0001 /* ---------------------------------------------------------------------- */ @@ -278,7 +276,7 @@ void PairREAX::write_reax_positions() FORTRAN(rsmall, RSMALL).na_local = nlocal; if (nlocal+nghost > ReaxParams::nat) - error->one("Reax_defs.h setting for NATDEF is too small"); + error->one(FLERR,"Reax_defs.h setting for NATDEF is too small"); jx = 0; jy = ReaxParams::nat; @@ -361,7 +359,7 @@ void PairREAX::write_reax_vlist() jjj = i+1; } if (nvpair >= nvpairmax) - error->one("Reax_defs.h setting for NNEIGHMAXDEF is too small"); + error->one(FLERR,"Reax_defs.h setting for NNEIGHMAXDEF is too small"); FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii; FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj; @@ -420,7 +418,7 @@ void PairREAX::write_reax_vlist() jjj = j+1; if (nvpair >= nvpairmax) - error->one("Reax_defs.h setting for NNEIGHMAXDEF is too small"); + error->one(FLERR,"Reax_defs.h setting for NNEIGHMAXDEF is too small"); FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii; FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj; @@ -485,7 +483,7 @@ void PairREAX::allocate() void PairREAX::settings(int narg, char **arg) { - if (narg != 0 && narg !=4) error->all("Illegal pair_style command"); + if (narg != 0 && narg !=4) error->all(FLERR,"Illegal pair_style command"); if (narg == 4) { hbcut = force->numeric(arg[0]); @@ -497,7 +495,7 @@ void PairREAX::settings(int narg, char **arg) (ihbnew != 0 && ihbnew != 1) || (itripstaball != 0 && itripstaball != 1) || precision <= 0.0) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); } } @@ -510,17 +508,17 @@ void PairREAX::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure filename is ffield.reax if (strcmp(arg[2],"ffield.reax") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to elements in potential file // map[i] = which element the Ith atom type is, -1 if NULL @@ -530,7 +528,7 @@ void PairREAX::coeff(int narg, char **arg) for (int i = 3; i < narg; i++) { if (strcmp(arg[i],"NULL") == 0) { map[i-2] = -1; - error->all("Cannot currently use pair reax with pair hybrid"); + error->all(FLERR,"Cannot currently use pair reax with pair hybrid"); continue; } map[i-2] = force->inumeric(arg[i]); @@ -545,7 +543,7 @@ void PairREAX::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -555,11 +553,11 @@ void PairREAX::coeff(int narg, char **arg) void PairREAX::init_style() { if (atom->tag_enable == 0) - error->all("Pair style reax requires atom IDs"); + error->all(FLERR,"Pair style reax requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style reax requires newton pair on"); + error->all(FLERR,"Pair style reax requires newton pair on"); if (strcmp(update->unit_style,"real") != 0 && comm->me == 0) - error->warning("Not using real units with pair reax"); + error->warning(FLERR,"Not using real units with pair reax"); int irequest = neighbor->request(this); neighbor->requests[irequest]->newton = 2; @@ -595,7 +593,7 @@ void PairREAX::init_style() double chi, eta, gamma; for (int itype = 1; itype <= atom->ntypes; itype++) { if (map[itype] < 1 || map[itype] > nelements) - error->all("Invalid REAX atom type"); + error->all(FLERR,"Invalid REAX atom type"); chi = FORTRAN(cbkchb, CBKCHB).chi[map[itype]-1]; eta = FORTRAN(cbkchb, CBKCHB).eta[map[itype]-1]; gamma = FORTRAN(cbkchb, CBKCHB).gam[map[itype]-1]; diff --git a/src/REPLICA/compute_event_displace.cpp b/src/REPLICA/compute_event_displace.cpp index 53e9d9f8f9..3f5f401c4b 100644 --- a/src/REPLICA/compute_event_displace.cpp +++ b/src/REPLICA/compute_event_displace.cpp @@ -37,14 +37,14 @@ using namespace LAMMPS_NS; ComputeEventDisplace::ComputeEventDisplace(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute event/displace command"); + if (narg != 4) error->all(FLERR,"Illegal compute event/displace command"); scalar_flag = 1; extscalar = 0; double displace_dist = atof(arg[3]); if (displace_dist <= 0.0) - error->all("Distance must be > 0 for compute event/displace"); + error->all(FLERR,"Distance must be > 0 for compute event/displace"); displace_distsq = displace_dist * displace_dist; // fix event ID will be set later by PRD @@ -69,12 +69,12 @@ void ComputeEventDisplace::init() if (id_event != NULL) { int ifix = modify->find_fix(id_event); - if (ifix < 0) error->all("Could not find compute event/displace fix ID"); + if (ifix < 0) error->all(FLERR,"Could not find compute event/displace fix ID"); fix_event = (FixEvent*) modify->fix[ifix]; if (strcmp(fix_event->style,"EVENT/PRD") != 0 && strcmp(fix_event->style,"EVENT/TAD") != 0) - error->all("Compute event/displace has invalid fix event assigned"); + error->all(FLERR,"Compute event/displace has invalid fix event assigned"); } triclinic = domain->triclinic; diff --git a/src/REPLICA/fix_event.cpp b/src/REPLICA/fix_event.cpp index 1b4f795e37..1277135502 100644 --- a/src/REPLICA/fix_event.cpp +++ b/src/REPLICA/fix_event.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; FixEvent::FixEvent(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix event command"); + if (narg != 3) error->all(FLERR,"Illegal fix event command"); restart_global = 1; diff --git a/src/REPLICA/fix_event_prd.cpp b/src/REPLICA/fix_event_prd.cpp index ac428f3713..84dedd18fd 100644 --- a/src/REPLICA/fix_event_prd.cpp +++ b/src/REPLICA/fix_event_prd.cpp @@ -35,7 +35,7 @@ using namespace LAMMPS_NS; FixEventPRD::FixEventPRD(LAMMPS *lmp, int narg, char **arg) : FixEvent(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix event command"); + if (narg != 3) error->all(FLERR,"Illegal fix event command"); restart_global = 1; diff --git a/src/REPLICA/fix_event_tad.cpp b/src/REPLICA/fix_event_tad.cpp index 950fcd6b80..7574b4873f 100644 --- a/src/REPLICA/fix_event_tad.cpp +++ b/src/REPLICA/fix_event_tad.cpp @@ -35,7 +35,7 @@ using namespace LAMMPS_NS; FixEventTAD::FixEventTAD(LAMMPS *lmp, int narg, char **arg) : FixEvent(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix event command"); + if (narg != 3) error->all(FLERR,"Illegal fix event command"); restart_global = 1; diff --git a/src/REPLICA/fix_neb.cpp b/src/REPLICA/fix_neb.cpp index 958aaa6cfe..d244ea7a8e 100644 --- a/src/REPLICA/fix_neb.cpp +++ b/src/REPLICA/fix_neb.cpp @@ -27,18 +27,15 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixNEB::FixNEB(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 4) error->all("Illegal fix neb command"); + if (narg != 4) error->all(FLERR,"Illegal fix neb command"); kspring = atof(arg[3]); - if (kspring <= 0.0) error->all("Illegal fix neb command"); + if (kspring <= 0.0) error->all(FLERR,"Illegal fix neb command"); // nreplica = number of partitions // ireplica = which world I am in universe @@ -98,7 +95,7 @@ void FixNEB::init() { int icompute = modify->find_compute(id_pe); if (icompute < 0) - error->all("Potential energy ID for fix neb does not exist"); + error->all(FLERR,"Potential energy ID for fix neb does not exist"); pe = modify->compute[icompute]; // turn off climbing mode, NEB command turns it on after init() @@ -156,7 +153,7 @@ void FixNEB::min_post_force(int vflag) double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; - if (nlocal != nebatoms) error->one("Atom count changed in fix neb"); + if (nlocal != nebatoms) error->one(FLERR,"Atom count changed in fix neb"); if (ireplica > 0) MPI_Irecv(xprev[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld,&request); diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index 6768b89acd..c8747aa811 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -101,9 +101,9 @@ NEB::~NEB() void NEB::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("NEB command before simulation box is defined"); + error->all(FLERR,"NEB command before simulation box is defined"); - if (narg != 6) error->universe_all("Illegal NEB command"); + if (narg != 6) error->universe_all(FLERR,"Illegal NEB command"); etol = atof(arg[0]); ftol = atof(arg[1]); @@ -114,11 +114,11 @@ void NEB::command(int narg, char **arg) // error checks - if (etol < 0.0) error->all("Illegal NEB command"); - if (ftol < 0.0) error->all("Illegal NEB command"); - if (nevery == 0) error->universe_all("Illegal NEB command"); + if (etol < 0.0) error->all(FLERR,"Illegal NEB command"); + if (ftol < 0.0) error->all(FLERR,"Illegal NEB command"); + if (nevery == 0) error->universe_all(FLERR,"Illegal NEB command"); if (n1steps % nevery || n2steps % nevery) - error->universe_all("Illegal NEB command"); + error->universe_all(FLERR,"Illegal NEB command"); // replica info @@ -130,13 +130,13 @@ void NEB::command(int narg, char **arg) // error checks - if (nreplica == 1) error->all("Cannot use NEB with a single replica"); + if (nreplica == 1) error->all(FLERR,"Cannot use NEB with a single replica"); if (nreplica != universe->nprocs) - error->all("Can only use NEB with 1-processor replicas"); + error->all(FLERR,"Can only use NEB with 1-processor replicas"); if (atom->sortfreq > 0) - error->all("Cannot use NEB with atom_modify sort enabled"); + error->all(FLERR,"Cannot use NEB with atom_modify sort enabled"); if (atom->map_style == 0) - error->all("Cannot use NEB unless atom map exists"); + error->all(FLERR,"Cannot use NEB unless atom map exists"); // read in file of final state atom coords and reset my coords @@ -163,7 +163,7 @@ void NEB::run() int ineb; for (ineb = 0; ineb < modify->nfix; ineb++) if (strcmp(modify->fix[ineb]->style,"neb") == 0) break; - if (ineb == modify->nfix) error->all("NEB requires use of fix neb"); + if (ineb == modify->nfix) error->all(FLERR,"NEB requires use of fix neb"); fneb = (FixNEB *) modify->fix[ineb]; nall = 4; @@ -180,7 +180,7 @@ void NEB::run() lmp->init(); if (update->minimize->searchflag) - error->all("NEB requires damped dynamics minimizer"); + error->all(FLERR,"NEB requires damped dynamics minimizer"); // setup regular NEB minimization @@ -192,7 +192,7 @@ void NEB::run() update->nsteps = n1steps; update->max_eval = n1steps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps for NEB"); + error->all(FLERR,"Too many timesteps for NEB"); update->minimize->setup(); @@ -259,7 +259,7 @@ void NEB::run() update->nsteps = n2steps; update->max_eval = n2steps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); update->minimize->init(); fneb->rclimber = top; @@ -354,7 +354,7 @@ void NEB::readfile(char *file) if (firstline) { if (atom->count_words(bufptr) == 4) firstline = 0; - else error->all("Incorrect format in NEB coordinate file"); + else error->all(FLERR,"Incorrect format in NEB coordinate file"); } sscanf(bufptr,"%d %lg %lg %lg",&tag,&xx,&yy,&zz); @@ -410,14 +410,14 @@ void NEB::open(char *file) sprintf(gunzip,"gunzip -c %s",file); fp = popen(gunzip,"r"); #else - error->one("Cannot open gzipped file"); + error->one(FLERR,"Cannot open gzipped file"); #endif } if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } } diff --git a/src/REPLICA/prd.cpp b/src/REPLICA/prd.cpp index 85d1b49062..909d7e35ec 100644 --- a/src/REPLICA/prd.cpp +++ b/src/REPLICA/prd.cpp @@ -63,15 +63,15 @@ void PRD::command(int narg, char **arg) // error checks if (domain->box_exist == 0) - error->all("PRD command before simulation box is defined"); + error->all(FLERR,"PRD command before simulation box is defined"); if (universe->nworlds != universe->nprocs && atom->map_style == 0) - error->all("Cannot use PRD with multi-processor replicas " + error->all(FLERR,"Cannot use PRD with multi-processor replicas " "unless atom map exists"); if (universe->nworlds == 1 && comm->me == 0) - error->warning("Running PRD with only one replica"); + error->warning(FLERR,"Running PRD with only one replica"); - if (narg < 7) error->universe_all("Illegal prd command"); + if (narg < 7) error->universe_all(FLERR,"Illegal prd command"); nsteps = atoi(arg[0]); t_event = atoi(arg[1]); @@ -87,11 +87,11 @@ void PRD::command(int narg, char **arg) // total # of timesteps must be multiple of t_event - if (t_event <= 0) error->universe_all("Invalid t_event in prd command"); + if (t_event <= 0) error->universe_all(FLERR,"Invalid t_event in prd command"); if (nsteps % t_event) - error->universe_all("PRD nsteps must be multiple of t_event"); + error->universe_all(FLERR,"PRD nsteps must be multiple of t_event"); if (t_corr % t_event) - error->universe_all("PRD t_corr must be multiple of t_event"); + error->universe_all(FLERR,"PRD t_corr must be multiple of t_event"); // local storage @@ -184,7 +184,7 @@ void PRD::command(int narg, char **arg) // necessary so it will know atom coords at last event int icompute = modify->find_compute(id_compute); - if (icompute < 0) error->all("Could not find compute ID for PRD"); + if (icompute < 0) error->all(FLERR,"Could not find compute ID for PRD"); compute_event = modify->compute[icompute]; compute_event->reset_extra_compute_fix("prd_event"); @@ -196,7 +196,7 @@ void PRD::command(int narg, char **arg) if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) { if (me == 0) - error->warning("Resetting reneighboring criteria during PRD"); + error->warning(FLERR,"Resetting reneighboring criteria during PRD"); } neighbor->every = 1; @@ -211,7 +211,7 @@ void PRD::command(int narg, char **arg) update->endstep = update->laststep = update->firststep + nsteps; update->restrict_output = 1; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); lmp->init(); @@ -227,14 +227,14 @@ void PRD::command(int narg, char **arg) for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->time_depend) - error->all("Cannot use PRD with a time-dependent fix defined"); + error->all(FLERR,"Cannot use PRD with a time-dependent fix defined"); for (int i = 0; i < domain->nregion; i++) if (domain->regions[i]->dynamic_check()) - error->all("Cannot use PRD with a time-dependent region defined"); + error->all(FLERR,"Cannot use PRD with a time-dependent region defined"); if (atom->sortfreq > 0) - error->all("Cannot use PRD with atom_modify sort enabled"); + error->all(FLERR,"Cannot use PRD with atom_modify sort enabled"); // perform PRD simulation @@ -499,7 +499,7 @@ void PRD::quench() update->nsteps = maxiter; update->endstep = update->laststep = update->firststep + maxiter; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many iterations"); + error->all(FLERR,"Too many iterations"); // full init works @@ -753,7 +753,7 @@ void PRD::replicate(int ireplica) void PRD::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal prd command"); + if (narg < 0) error->all(FLERR,"Illegal prd command"); // set defaults @@ -776,42 +776,42 @@ void PRD::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"min") == 0) { - if (iarg+5 > narg) error->all("Illegal prd command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal prd command"); etol = atof(arg[iarg+1]); ftol = atof(arg[iarg+2]); maxiter = atoi(arg[iarg+3]); maxeval = atoi(arg[iarg+4]); - if (maxiter < 0) error->all("Illegal prd command"); + if (maxiter < 0) error->all(FLERR,"Illegal prd command"); iarg += 5; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+2 > narg) error->all("Illegal prd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal prd command"); temp_flag = 1; temp_dephase = atof(arg[iarg+1]); - if (temp_dephase <= 0.0) error->all("Illegal prd command"); + if (temp_dephase <= 0.0) error->all(FLERR,"Illegal prd command"); iarg += 2; } else if (strcmp(arg[iarg],"vel") == 0) { - if (iarg+3 > narg) error->all("Illegal prd command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal prd command"); delete [] loop_setting; delete [] dist_setting; if (strcmp(arg[iarg+1],"all") == 0) loop_setting = NULL; else if (strcmp(arg[iarg+1],"local") == 0) loop_setting = NULL; else if (strcmp(arg[iarg+1],"geom") == 0) loop_setting = NULL; - else error->all("Illegal prd command"); + else error->all(FLERR,"Illegal prd command"); int n = strlen(arg[iarg+1]) + 1; loop_setting = new char[n]; strcpy(loop_setting,arg[iarg+1]); if (strcmp(arg[iarg+2],"uniform") == 0) dist_setting = NULL; else if (strcmp(arg[iarg+2],"gaussian") == 0) dist_setting = NULL; - else error->all("Illegal prd command"); + else error->all(FLERR,"Illegal prd command"); n = strlen(arg[iarg+2]) + 1; dist_setting = new char[n]; strcpy(dist_setting,arg[iarg+2]); iarg += 3; - } else error->all("Illegal prd command"); + } else error->all(FLERR,"Illegal prd command"); } } diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp index 8241d407a7..3f4ba9c160 100644 --- a/src/REPLICA/tad.cpp +++ b/src/REPLICA/tad.cpp @@ -80,17 +80,17 @@ void TAD::command(int narg, char **arg) // error checks if (domain->box_exist == 0) - error->all("Tad command before simulation box is defined"); + error->all(FLERR,"Tad command before simulation box is defined"); if (universe->nworlds == 1) - error->all("Cannot use TAD with a single replica for NEB"); + error->all(FLERR,"Cannot use TAD with a single replica for NEB"); if (universe->nworlds != universe->nprocs) - error->all("Can only use TAD with 1-processor replicas for NEB"); + error->all(FLERR,"Can only use TAD with 1-processor replicas for NEB"); if (atom->sortfreq > 0) - error->all("Cannot use TAD with atom_modify sort enabled for NEB"); + error->all(FLERR,"Cannot use TAD with atom_modify sort enabled for NEB"); if (atom->map_style == 0) - error->all("Cannot use TAD unless atom map exists for NEB"); + error->all(FLERR,"Cannot use TAD unless atom map exists for NEB"); - if (narg < 7) error->universe_all("Illegal tad command"); + if (narg < 7) error->universe_all(FLERR,"Illegal tad command"); nsteps = atoi(arg[0]); t_event = atoi(arg[1]); @@ -106,15 +106,15 @@ void TAD::command(int narg, char **arg) // total # of timesteps must be multiple of t_event - if (t_event <= 0) error->universe_all("Invalid t_event in tad command"); + if (t_event <= 0) error->universe_all(FLERR,"Invalid t_event in tad command"); if (nsteps % t_event) - error->universe_all("TAD nsteps must be multiple of t_event"); + error->universe_all(FLERR,"TAD nsteps must be multiple of t_event"); if (delta_conf <= 0.0 || delta_conf >= 1.0) - error->universe_all("Invalid delta_conf in tad command"); + error->universe_all(FLERR,"Invalid delta_conf in tad command"); if (tmax <= 0.0) - error->universe_all("Invalid tmax in tad command"); + error->universe_all(FLERR,"Invalid tmax in tad command"); // deltconf = (ln(1/delta))/freq_min (timestep units) @@ -171,7 +171,7 @@ void TAD::command(int narg, char **arg) // necessary so it will know atom coords at last event int icompute = modify->find_compute(id_compute); - if (icompute < 0) error->all("Could not find compute ID for TAD"); + if (icompute < 0) error->all(FLERR,"Could not find compute ID for TAD"); compute_event = modify->compute[icompute]; compute_event->reset_extra_compute_fix("tad_event"); @@ -183,7 +183,7 @@ void TAD::command(int narg, char **arg) if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) { if (me_universe == 0) - error->warning("Resetting reneighboring criteria during TAD"); + error->warning(FLERR,"Resetting reneighboring criteria during TAD"); } neighbor->every = 1; @@ -198,7 +198,7 @@ void TAD::command(int narg, char **arg) update->endstep = update->laststep = update->firststep + nsteps; update->restrict_output = 1; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); lmp->init(); @@ -470,7 +470,7 @@ void TAD::quench() update->nsteps = maxiter; update->endstep = update->laststep = update->firststep + maxiter; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many iterations"); + error->all(FLERR,"Too many iterations"); // full init works @@ -570,7 +570,7 @@ void TAD::log_event(int ievent) void TAD::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal tad command"); + if (narg < 0) error->all(FLERR,"Illegal tad command"); // set defaults @@ -594,18 +594,18 @@ void TAD::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"min") == 0) { - if (iarg+5 > narg) error->all("Illegal tad command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal tad command"); etol = atof(arg[iarg+1]); ftol = atof(arg[iarg+2]); maxiter = atoi(arg[iarg+3]); maxeval = atoi(arg[iarg+4]); if (maxiter < 0 || maxeval < 0 || etol < 0.0 || ftol < 0.0 ) - error->all("Illegal tad command"); + error->all(FLERR,"Illegal tad command"); iarg += 5; } else if (strcmp(arg[iarg],"neb") == 0) { - if (iarg+6 > narg) error->all("Illegal tad command"); + if (iarg+6 > narg) error->all(FLERR,"Illegal tad command"); etol_neb = atof(arg[iarg+1]); ftol_neb = atof(arg[iarg+2]); n1steps_neb = atoi(arg[iarg+3]); @@ -613,11 +613,11 @@ void TAD::options(int narg, char **arg) nevery_neb = atoi(arg[iarg+5]); if (etol_neb < 0.0 || ftol_neb < 0.0 || n1steps_neb < 0 || n2steps_neb < 0 || - nevery_neb < 0) error->all("Illegal tad command"); + nevery_neb < 0) error->all(FLERR,"Illegal tad command"); iarg += 6; } else if (strcmp(arg[iarg],"min_style") == 0) { - if (iarg+2 > narg) error->all("Illegal tad command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal tad command"); int n = strlen(arg[iarg+1]) + 1; delete [] min_style; min_style = new char[n]; @@ -625,7 +625,7 @@ void TAD::options(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg],"neb_style") == 0) { - if (iarg+2 > narg) error->all("Illegal tad command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal tad command"); int n = strlen(arg[iarg+1]) + 1; delete [] min_style_neb; min_style_neb = new char[n]; @@ -634,7 +634,7 @@ void TAD::options(int narg, char **arg) } else if (strcmp(arg[iarg],"neb_log") == 0) { delete [] neb_logfilename; - if (iarg+2 > narg) error->all("Illegal tad command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal tad command"); if (strcmp(arg[iarg+1],"none") == 0) neb_logfilename = NULL; else { int n = strlen(arg[iarg+1]) + 1; @@ -642,7 +642,7 @@ void TAD::options(int narg, char **arg) strcpy(neb_logfilename,arg[iarg+1]); } iarg += 2; - } else error->all("Illegal tad command"); + } else error->all(FLERR,"Illegal tad command"); } } diff --git a/src/REPLICA/temper.cpp b/src/REPLICA/temper.cpp index ea8fcfaab6..d95fb3d89b 100644 --- a/src/REPLICA/temper.cpp +++ b/src/REPLICA/temper.cpp @@ -65,10 +65,10 @@ Temper::~Temper() void Temper::command(int narg, char **arg) { if (universe->nworlds == 1) - error->all("Must have more than one processor partition to temper"); + error->all(FLERR,"Must have more than one processor partition to temper"); if (domain->box_exist == 0) - error->all("Temper command before simulation box is defined"); - if (narg != 6 && narg != 7) error->universe_all("Illegal temper command"); + error->all(FLERR,"Temper command before simulation box is defined"); + if (narg != 6 && narg != 7) error->universe_all(FLERR,"Illegal temper command"); int nsteps = atoi(arg[0]); nevery = atoi(arg[1]); @@ -77,7 +77,7 @@ void Temper::command(int narg, char **arg) for (whichfix = 0; whichfix < modify->nfix; whichfix++) if (strcmp(arg[3],modify->fix[whichfix]->id) == 0) break; if (whichfix == modify->nfix) - error->universe_all("Tempering fix ID is not defined"); + error->universe_all(FLERR,"Tempering fix ID is not defined"); seed_swap = atoi(arg[4]); seed_boltz = atoi(arg[5]); @@ -87,10 +87,10 @@ void Temper::command(int narg, char **arg) // swap frequency must evenly divide total # of timesteps - if (nevery == 0) error->universe_all("Invalid frequency in temper command"); + if (nevery == 0) error->universe_all(FLERR,"Invalid frequency in temper command"); nswaps = nsteps/nevery; if (nswaps*nevery != nsteps) - error->universe_all("Non integer # of swaps in temper command"); + error->universe_all(FLERR,"Non integer # of swaps in temper command"); // fix style must be appropriate for temperature control @@ -98,7 +98,7 @@ void Temper::command(int narg, char **arg) (strcmp(modify->fix[whichfix]->style,"langevin") != 0) && (strcmp(modify->fix[whichfix]->style,"temp/berendsen") != 0) && (strcmp(modify->fix[whichfix]->style,"temp/rescale") != 0)) - error->universe_all("Tempering temperature fix is not valid"); + error->universe_all(FLERR,"Tempering temperature fix is not valid"); // setup for long tempering run @@ -107,7 +107,7 @@ void Temper::command(int narg, char **arg) update->beginstep = update->firststep = update->ntimestep; update->endstep = update->laststep = update->firststep + nsteps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); lmp->init(); @@ -123,7 +123,7 @@ void Temper::command(int narg, char **arg) // notify compute it will be called at first swap int id = modify->find_compute("thermo_pe"); - if (id < 0) error->all("Tempering could not find thermo_pe compute"); + if (id < 0) error->all(FLERR,"Tempering could not find thermo_pe compute"); Compute *pe_compute = modify->compute[id]; pe_compute->addstep(update->ntimestep + nevery); diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp index 8036c27248..42fd494f96 100644 --- a/src/SHOCK/fix_append_atoms.cpp +++ b/src/SHOCK/fix_append_atoms.cpp @@ -41,7 +41,7 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : box_change = 1; time_depend = 1; - if (narg < 4) error->all("Illegal fix append_atoms command"); + if (narg < 4) error->all(FLERR,"Illegal fix append_atoms command"); scaleflag = 1; spatflag=0; @@ -61,41 +61,41 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"xlo") == 0) { - error->all("Only zhi currently implemented for append_atoms"); + error->all(FLERR,"Only zhi currently implemented for append_atoms"); xloflag = 1; iarg++; - if (domain->boundary[0][0] != 3) error->all("Must shrink-wrap with minimum the append boundary"); + if (domain->boundary[0][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"xhi") == 0) { - error->all("Only zhi currently implemented for append_atom"); + error->all(FLERR,"Only zhi currently implemented for append_atom"); xhiflag = 1; iarg++; - if (domain->boundary[0][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[0][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"ylo") == 0) { - error->all("Only zhi currently implemented for append_atom"); + error->all(FLERR,"Only zhi currently implemented for append_atom"); yloflag = 1; iarg++; - if (domain->boundary[1][0] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"yhi") == 0) { - error->all("Only zhi currently implemented for append_atom"); + error->all(FLERR,"Only zhi currently implemented for append_atom"); yhiflag = 1; iarg++; - if (domain->boundary[1][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"zlo") == 0) { - error->all("Only zhi currently implemented for append_atom"); + error->all(FLERR,"Only zhi currently implemented for append_atom"); zloflag = 1; iarg++; - if (domain->boundary[2][0] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"zhi") == 0) { zhiflag = 1; iarg++; - if (domain->boundary[2][1] != 3) error->all("Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); } else if (strcmp(arg[iarg],"freq") == 0) { - if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); freq = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"spatial") == 0) { - if (iarg+3 > narg) error->all("Illegal fix append_atoms command"); - if (strcmp(arg[iarg+1],"f_") == 0) error->all("Bad fix ID in fix append_atoms command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix append_atoms command"); + if (strcmp(arg[iarg+1],"f_") == 0) error->all(FLERR,"Bad fix ID in fix append_atoms command"); spatflag = 1; int n = strlen(arg[iarg+1]); spatlead = atof(arg[iarg+2]); @@ -108,56 +108,56 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : iarg += 3; // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL } else if (strcmp(arg[iarg],"size") == 0) { - if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); size = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix append_atoms command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix append_atoms command"); + else error->all(FLERR,"Illegal fix append_atoms command"); iarg += 2; } else if (strcmp(arg[iarg],"random") == 0) { - if (iarg+5 > narg) error->all("Illegal fix append_atoms command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix append_atoms command"); ranflag = 1; ranx = atof(arg[iarg+1]); rany = atof(arg[iarg+2]); ranz = atof(arg[iarg+3]); xseed = atoi(arg[iarg+4]); - if (xseed <= 0) error->all("Illegal fix append_atoms command"); + if (xseed <= 0) error->all(FLERR,"Illegal fix append_atoms command"); randomx = new RanMars(lmp,xseed + comm->me); iarg += 5; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+5 > narg) error->all("Illegal fix append_atoms command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix append_atoms command"); tempflag = 1; t_target = atof(arg[iarg+1]); t_period = atof(arg[iarg+2]); tseed = atoi(arg[iarg+3]); t_extent = atof(arg[iarg+4]); - if (t_target <= 0) error->all("Illegal fix append_atoms command"); - if (t_period <= 0) error->all("Illegal fix append_atoms command"); - if (t_extent <= 0) error->all("Illegal fix append_atoms command"); - if (tseed <= 0) error->all("Illegal fix append_atoms command"); + if (t_target <= 0) error->all(FLERR,"Illegal fix append_atoms command"); + if (t_period <= 0) error->all(FLERR,"Illegal fix append_atoms command"); + if (t_extent <= 0) error->all(FLERR,"Illegal fix append_atoms command"); + if (tseed <= 0) error->all(FLERR,"Illegal fix append_atoms command"); randomt = new RanMars(lmp,tseed + comm->me); gfactor1 = new double[atom->ntypes+1]; gfactor2 = new double[atom->ntypes+1]; iarg += 5; - } else error->all("Illegal fix append_atoms command"); + } else error->all(FLERR,"Illegal fix append_atoms command"); } if ((xloflag || xhiflag) && domain->xperiodic) - error->all("Cannot use append_atoms in periodic dimension"); + error->all(FLERR,"Cannot use append_atoms in periodic dimension"); if ((yloflag || yhiflag) && domain->yperiodic) - error->all("Cannot use append_atoms in periodic dimension"); + error->all(FLERR,"Cannot use append_atoms in periodic dimension"); if ((zloflag || zhiflag) && domain->zperiodic) - error->all("Cannot use append_atoms in periodic dimension"); + error->all(FLERR,"Cannot use append_atoms in periodic dimension"); - if (domain->triclinic == 1) error->all("Cannot append atoms to a triclinic box"); + if (domain->triclinic == 1) error->all(FLERR,"Cannot append atoms to a triclinic box"); // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of fix append_atoms with undefined lattice"); + error->all(FLERR,"Use of fix append_atoms with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -226,7 +226,7 @@ int FixAppendAtoms::get_spatial() if (update->ntimestep % freq == 0) { int ifix = modify->find_fix(spatialid); if (ifix < 0) - error->all("Fix ID for fix ave/spatial does not exist"); + error->all(FLERR,"Fix ID for fix ave/spatial does not exist"); Fix *fix = modify->fix[ifix]; int failed = 0; @@ -382,7 +382,7 @@ void FixAppendAtoms::pre_exchange() nbasis = domain->lattice->nbasis; basistype = new int[nbasis]; for (int i = 0; i < nbasis; i++) basistype[i] = 1; - } else error->all("must define lattice to append_atoms"); + } else error->all(FLERR,"must define lattice to append_atoms"); double bboxlo[3],bboxhi[3]; diff --git a/src/SHOCK/fix_msst.cpp b/src/SHOCK/fix_msst.cpp index 90cb7b3241..1ba47ee146 100644 --- a/src/SHOCK/fix_msst.cpp +++ b/src/SHOCK/fix_msst.cpp @@ -41,7 +41,7 @@ using namespace LAMMPS_NS; FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix msst command"); + if (narg < 4) error->all(FLERR,"Illegal fix msst command"); restart_global = 1; box_change = 1; @@ -76,12 +76,12 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) : else if ( strcmp(arg[3],"z") == 0 ) direction = 2; else { - error->all("Illegal fix msst command"); + error->all(FLERR,"Illegal fix msst command"); } velocity = atof(arg[4]); if ( velocity < 0 ) - error->all("Illegal fix msst command"); + error->all(FLERR,"Illegal fix msst command"); for ( int iarg = 5; iarg < narg; iarg++ ) { if ( strcmp(arg[iarg],"q") == 0 ) { @@ -105,9 +105,9 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) : } else if ( strcmp(arg[iarg],"tscale") == 0 ) { tscale = atof(arg[iarg+1]); if (tscale < 0.0 || tscale > 1.0) - error->all("Fix msst tscale must satisfy 0 <= tscale < 1"); + error->all(FLERR,"Fix msst tscale must satisfy 0 <= tscale < 1"); iarg++; - } else error->all("Illegal fix msst command"); + } else error->all(FLERR,"Illegal fix msst command"); } if (comm->me == 0) { @@ -161,7 +161,7 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) : // check for periodicity in controlled dimensions - if (domain->nonperiodic) error->all("Fix msst requires a periodic box"); + if (domain->nonperiodic) error->all(FLERR,"Fix msst requires a periodic box"); // create a new compute temp style // id = fix-ID + temp @@ -267,7 +267,7 @@ int FixMSST::setmask() void FixMSST::init() { if (atom->mass == NULL) - error->all("Cannot use fix msst without per-type mass defined"); + error->all(FLERR,"Cannot use fix msst without per-type mass defined"); // set compute ptrs @@ -275,13 +275,13 @@ void FixMSST::init() int ipress = modify->find_compute(id_press); int ipe = modify->find_compute(id_pe); if (itemp < 0 || ipress < 0|| ipe < 0) - error->all("Could not find fix msst compute ID"); + error->all(FLERR,"Could not find fix msst compute ID"); if (modify->compute[itemp]->tempflag == 0) - error->all("Fix msst compute ID does not compute temperature"); + error->all(FLERR,"Fix msst compute ID does not compute temperature"); if (modify->compute[ipress]->pressflag == 0) - error->all("Fix msst compute ID does not compute pressure"); + error->all(FLERR,"Fix msst compute ID does not compute pressure"); if (modify->compute[ipe]->peflag == 0) - error->all("Fix msst compute ID does not compute potential energy"); + error->all(FLERR,"Fix msst compute ID does not compute potential energy"); temperature = modify->compute[itemp]; pressure = modify->compute[ipress]; @@ -739,7 +739,7 @@ void FixMSST::restart(char *buf) int FixMSST::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -750,18 +750,18 @@ int FixMSST::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for MSST is not for group all"); + error->warning(FLERR,"Temperature for MSST is not for group all"); return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (pflag) { modify->delete_compute(id_press); pflag = 0; @@ -772,11 +772,11 @@ int FixMSST::modify_param(int narg, char **arg) strcpy(id_press,arg[1]); int icompute = modify->find_compute(id_press); - if (icompute < 0) error->all("Could not find fix_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); return 2; } return 0; diff --git a/src/SHOCK/fix_nphug.cpp b/src/SHOCK/fix_nphug.cpp index 85463535c9..32230940d5 100644 --- a/src/SHOCK/fix_nphug.cpp +++ b/src/SHOCK/fix_nphug.cpp @@ -60,7 +60,7 @@ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : if (p_start[0] != p_stop[0] || p_start[1] != p_stop[1] || p_start[2] != p_stop[2]) - error->all("Invalid argument for fix nphug"); + error->all(FLERR,"Invalid argument for fix nphug"); // uniaxial = 0 means hydrostatic compression // uniaxial = 1 means uniaxial compression @@ -96,7 +96,7 @@ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : uniaxial = 1; idir = 2; - } else error->all("Invalid argument for fix nphug"); + } else error->all(FLERR,"Invalid argument for fix nphug"); // triclinic hydrostatic compression @@ -109,13 +109,13 @@ FixNPHug::FixNPHug(LAMMPS *lmp, int narg, char **arg) : p_start[5] == 0.0 ) uniaxial = 0; - else error->all("Invalid argument for fix nphug"); + else error->all(FLERR,"Invalid argument for fix nphug"); } if (!tstat_flag) - error->all("Temperature control must be used with fix nphug"); + error->all(FLERR,"Temperature control must be used with fix nphug"); if (!pstat_flag) - error->all("Pressure control must be used with fix nphug"); + error->all(FLERR,"Pressure control must be used with fix nphug"); // create a new compute temp style // id = fix-ID + temp @@ -195,7 +195,7 @@ void FixNPHug::init() int icompute = modify->find_compute(id_pe); if (icompute < 0) - error->all("Potential energy ID for fix nvt/nph/npt does not exist"); + error->all(FLERR,"Potential energy ID for fix nvt/nph/npt does not exist"); pe = modify->compute[icompute]; } @@ -440,17 +440,17 @@ void FixNPHug::restart(char *buf) int FixNPHug::modify_param(int narg, char **arg) { if (strcmp(arg[0],"e0") == 0) { - if (narg < 2) error->all("Illegal fix nphug command"); + if (narg < 2) error->all(FLERR,"Illegal fix nphug command"); e0 = atof(arg[1]); e0_set = 1; return 2; } else if (strcmp(arg[0],"v0") == 0) { - if (narg < 2) error->all("Illegal fix nphug command"); + if (narg < 2) error->all(FLERR,"Illegal fix nphug command"); v0 = atof(arg[1]); v0_set = 1; return 2; } else if (strcmp(arg[0],"p0") == 0) { - if (narg < 2) error->all("Illegal fix nphug command"); + if (narg < 2) error->all(FLERR,"Illegal fix nphug command"); p0 = atof(arg[1]); p0_set = 1; return 2; diff --git a/src/SHOCK/fix_wall_piston.cpp b/src/SHOCK/fix_wall_piston.cpp index e639b62858..2d610ea2e0 100644 --- a/src/SHOCK/fix_wall_piston.cpp +++ b/src/SHOCK/fix_wall_piston.cpp @@ -37,7 +37,7 @@ FixWallPiston::FixWallPiston(LAMMPS *lmp, int narg, char **arg) : box_change = 1; time_depend = 1; - if (narg < 4) error->all("Illegal fix wall/piston command"); + if (narg < 4) error->all(FLERR,"Illegal fix wall/piston command"); randomt = NULL; tempflag = 0; @@ -54,38 +54,38 @@ FixWallPiston::FixWallPiston(LAMMPS *lmp, int narg, char **arg) : int iarg = 0; iarg = 3; while (iarg < narg) { - if (strcmp(arg[iarg],"xlo") == 0) { error->all("Fix wall/piston command only available at zlo"); - } else if (strcmp(arg[iarg],"ylo") == 0) { error->all("Fix wall/piston command only available at zlo"); + if (strcmp(arg[iarg],"xlo") == 0) { error->all(FLERR,"Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"ylo") == 0) { error->all(FLERR,"Fix wall/piston command only available at zlo"); } else if (strcmp(arg[iarg],"zlo") == 0) { zloflag = 1; iarg++; - if (domain->boundary[2][0] != 2) error->all("Must shrink-wrap piston boundary"); - } else if (strcmp(arg[iarg],"xhi") == 0) { error->all("Fix wall/piston command only available at zlo"); - } else if (strcmp(arg[iarg],"yhi") == 0) { error->all("Fix wall/piston command only available at zlo"); - } else if (strcmp(arg[iarg],"zhi") == 0) { error->all("Fix wall/piston command only available at zlo"); + if (domain->boundary[2][0] != 2) error->all(FLERR,"Must shrink-wrap piston boundary"); + } else if (strcmp(arg[iarg],"xhi") == 0) { error->all(FLERR,"Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"yhi") == 0) { error->all(FLERR,"Fix wall/piston command only available at zlo"); + } else if (strcmp(arg[iarg],"zhi") == 0) { error->all(FLERR,"Fix wall/piston command only available at zlo"); } else if (strcmp(arg[iarg],"vel") == 0) { - if (iarg+4 > narg) error->all("Illegal fix wall/piston command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix wall/piston command"); vx = atof(arg[iarg+1]); vy = atof(arg[iarg+2]); vz = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"pos") == 0) { - if (iarg+4 > narg) error->all("Illegal fix wall/piston command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix wall/piston command"); x0 = atof(arg[iarg+1]); y0 = atof(arg[iarg+2]); z0 = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+5 > narg) error->all("Illegal fix wall/pistons command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix wall/pistons command"); tempflag = 1; t_target = atof(arg[iarg+1]); t_period = atof(arg[iarg+2]); tseed = atoi(arg[iarg+3]); t_extent = atof(arg[iarg+4]); - if (t_target <= 0) error->all("Illegal fix wall/piston command"); - if (t_period <= 0) error->all("Illegal fix wall/piston command"); - if (t_extent <= 0) error->all("Illegal fix wall/piston command"); - if (tseed <= 0) error->all("Illegal fix wall/pistons command"); + if (t_target <= 0) error->all(FLERR,"Illegal fix wall/piston command"); + if (t_period <= 0) error->all(FLERR,"Illegal fix wall/piston command"); + if (t_extent <= 0) error->all(FLERR,"Illegal fix wall/piston command"); + if (tseed <= 0) error->all(FLERR,"Illegal fix wall/pistons command"); randomt = new RanMars(lmp,tseed + comm->me); gfactor1 = new double[atom->ntypes+1]; gfactor2 = new double[atom->ntypes+1]; @@ -113,26 +113,26 @@ FixWallPiston::FixWallPiston(LAMMPS *lmp, int narg, char **arg) : rampNL5flag = 1; iarg++; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix wall/piston command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall/piston command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix wall/piston command"); + else error->all(FLERR,"Illegal fix wall/piston command"); iarg += 2; - } else error->all("Illegal fix wall/piston command"); + } else error->all(FLERR,"Illegal fix wall/piston command"); } - if (vx < 0.0 || vy < 0.0 || vz < 0.0) error->all("Illegal fix wall/piston velocity"); + if (vx < 0.0 || vy < 0.0 || vz < 0.0) error->all(FLERR,"Illegal fix wall/piston velocity"); if ((xloflag || xhiflag) && domain->xperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); if ((yloflag || yhiflag) && domain->yperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); if ((zloflag || zhiflag) && domain->zperiodic) - error->all("Cannot use wall in periodic dimension"); + error->all(FLERR,"Cannot use wall in periodic dimension"); // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of fix wall/piston with undefined lattice"); + error->all(FLERR,"Use of fix wall/piston with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -209,7 +209,7 @@ void FixWallPiston::post_integrate() zlo = z0 + paccelz * (0.5*tt + 1.0/(angfreq*angfreq) - 1.0/(angfreq*angfreq)*cos(angfreq*t)); vz = paccelz * (t + 1.0/angfreq*sin(angfreq*t)); } - else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + else { error->all(FLERR,"NL ramp in wall/piston only implemented in zlo for now"); } } else if (rampNL2flag) { paccelz = maxvz / tott; @@ -219,7 +219,7 @@ void FixWallPiston::post_integrate() zlo = z0 + paccelz * (0.5*tt + 4.0/(3.0*angfreq*angfreq)*(1.0-cos(angfreq*t)) + 1.0/(6.0*angfreq*angfreq)*(1.0-cos(2.0*angfreq*t))); vz = paccelz * (t + 4.0/(3.0*angfreq)*sin(angfreq*t) + 1.0/(3.0*angfreq)*sin(2.0*angfreq*t)); } - else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + else { error->all(FLERR,"NL ramp in wall/piston only implemented in zlo for now"); } } else if (rampNL3flag) { paccelz = maxvz / tott; @@ -228,7 +228,7 @@ void FixWallPiston::post_integrate() zlo = z0 + paccelz*tott*tott/2.5 * (t2p5 ); vz = paccelz * tott * (t1p5 ); } - else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + else { error->all(FLERR,"NL ramp in wall/piston only implemented in zlo for now"); } } else if (rampNL4flag) { paccelz = maxvz / tott; @@ -237,7 +237,7 @@ void FixWallPiston::post_integrate() zlo = z0 + paccelz/tott/3.0 * (ttt); vz = paccelz / tott * (tt); } - else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + else { error->all(FLERR,"NL ramp in wall/piston only implemented in zlo for now"); } } else if (rampNL5flag) { paccelz = maxvz / tott; @@ -246,7 +246,7 @@ void FixWallPiston::post_integrate() zlo = z0 + paccelz/tott/tott/4.0 * (tttt); vz = paccelz / tott / tott * (ttt); } - else { error->all("NL ramp in wall/piston only implemented in zlo for now"); } + else { error->all(FLERR,"NL ramp in wall/piston only implemented in zlo for now"); } } else { if (zloflag) { zlo = z0 + vz * t; } diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index 1516e23d51..ec0d07d20d 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -53,9 +53,6 @@ enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp #define BIG 1.0e20 #define VBINSIZE 5 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - //#define SRD_DEBUG 1 //#define SRD_DEBUG_ATOMID 58 //#define SRD_DEBUG_TIMESTEP 449 @@ -64,7 +61,7 @@ enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 8) error->all("Illegal fix srd command"); + if (narg < 8) error->all(FLERR,"Illegal fix srd command"); restart_pbc = 1; vector_flag = 1; @@ -101,85 +98,85 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) int iarg = 8; while (iarg < narg) { if (strcmp(arg[iarg],"lamda") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); lamda = atof(arg[iarg+1]); lamdaflag = 1; iarg += 2; } else if (strcmp(arg[iarg],"collision") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"slip") == 0) collidestyle = SLIP; else if (strcmp(arg[iarg+1],"noslip") == 0) collidestyle = NOSLIP; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else if (strcmp(arg[iarg],"overlap") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"yes") == 0) overlap = 1; else if (strcmp(arg[iarg+1],"no") == 0) overlap = 0; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else if (strcmp(arg[iarg],"inside") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"error") == 0) insideflag = INSIDE_ERROR; else if (strcmp(arg[iarg+1],"warn") == 0) insideflag = INSIDE_WARN; else if (strcmp(arg[iarg+1],"ignore") == 0) insideflag = INSIDE_IGNORE; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else if (strcmp(arg[iarg],"exact") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"yes") == 0) exactflag = 1; else if (strcmp(arg[iarg+1],"no") == 0) exactflag = 0; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else if (strcmp(arg[iarg],"radius") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); radfactor = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"bounce") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); maxbounceallow = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"search") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); gridsearch = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"cubic") == 0) { - if (iarg+3 > narg) error->all("Illegal fix srd command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"error") == 0) cubicflag = CUBIC_ERROR; else if (strcmp(arg[iarg+1],"warn") == 0) cubicflag = CUBIC_WARN; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); cubictol = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"shift") == 0) { - if (iarg+3 > narg) error->all("Illegal fix srd command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix srd command"); else if (strcmp(arg[iarg+1],"no") == 0) shiftuser = SHIFT_NO; else if (strcmp(arg[iarg+1],"yes") == 0) shiftuser = SHIFT_YES; else if (strcmp(arg[iarg+1],"possible") == 0) shiftuser = SHIFT_POSSIBLE; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); shiftseed = atoi(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"stream") == 0) { - if (iarg+2 > narg) error->all("Illegal fix srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); if (strcmp(arg[iarg+1],"yes") == 0) streamflag = 1; else if (strcmp(arg[iarg+1],"no") == 0) streamflag = 0; - else error->all("Illegal fix srd command"); + else error->all(FLERR,"Illegal fix srd command"); iarg += 2; - } else error->all("Illegal fix srd command"); + } else error->all(FLERR,"Illegal fix srd command"); } // error check - if (nevery <= 0) error->all("Illegal fix srd command"); - if (bigexist && biggroup < 0) error->all("Could not find fix srd group ID"); - if (gridsrd <= 0.0) error->all("Illegal fix srd command"); - if (temperature_srd <= 0.0) error->all("Illegal fix srd command"); - if (seed <= 0) error->all("Illegal fix srd command"); - if (radfactor <= 0.0) error->all("Illegal fix srd command"); - if (maxbounceallow < 0) error->all("Illegal fix srd command"); - if (lamdaflag && lamda <= 0.0) error->all("Illegal fix srd command"); - if (gridsearch <= 0.0) error->all("Illegal fix srd command"); - if (cubictol < 0.0 || cubictol > 1.0) error->all("Illegal fix srd command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix srd command"); + if (bigexist && biggroup < 0) error->all(FLERR,"Could not find fix srd group ID"); + if (gridsrd <= 0.0) error->all(FLERR,"Illegal fix srd command"); + if (temperature_srd <= 0.0) error->all(FLERR,"Illegal fix srd command"); + if (seed <= 0) error->all(FLERR,"Illegal fix srd command"); + if (radfactor <= 0.0) error->all(FLERR,"Illegal fix srd command"); + if (maxbounceallow < 0) error->all(FLERR,"Illegal fix srd command"); + if (lamdaflag && lamda <= 0.0) error->all(FLERR,"Illegal fix srd command"); + if (gridsearch <= 0.0) error->all(FLERR,"Illegal fix srd command"); + if (cubictol < 0.0 || cubictol > 1.0) error->all(FLERR,"Illegal fix srd command"); if ((shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE) && - shiftseed <= 0) error->all("Illegal fix srd command"); + shiftseed <= 0) error->all(FLERR,"Illegal fix srd command"); // initialize Marsaglia RNG with processor-unique seed @@ -290,13 +287,13 @@ void FixSRD::init() { // error checks - if (force->newton_pair == 0) error->all("Fix srd requires newton pair on"); + if (force->newton_pair == 0) error->all(FLERR,"Fix srd requires newton pair on"); if (bigexist && comm->ghost_velocity == 0) - error->all("Fix srd requires ghost atoms store velocity"); + error->all(FLERR,"Fix srd requires ghost atoms store velocity"); if (bigexist && collidestyle == NOSLIP && !atom->torque_flag) - error->all("Fix SRD no-slip requires atom attribute torque"); + error->all(FLERR,"Fix SRD no-slip requires atom attribute torque"); if (initflag && update->dt != dt_big) - error->all("Cannot change timestep once fix srd is setup"); + error->all(FLERR,"Cannot change timestep once fix srd is setup"); // orthogonal vs triclinic simulation box // could be static or shearing box @@ -308,7 +305,7 @@ void FixSRD::init() wallexist = 0; for (int m = 0; m < modify->nfix; m++) { if (strcmp(modify->fix[m]->style,"wall/srd") == 0) { - if (wallexist) error->all("Cannot use fix wall/srd more than once"); + if (wallexist) error->all(FLERR,"Cannot use fix wall/srd more than once"); wallexist = 1; wallfix = (FixWallSRD *) modify->fix[m]; nwall = wallfix->nwall; @@ -320,7 +317,7 @@ void FixSRD::init() fwall = wallfix->fwall; walltrigger = 0.5 * neighbor->skin; if (wallfix->overlap && overlap == 0 && me == 0) - error->warning("Fix SRD walls overlap but fix srd overlap not set"); + error->warning(FLERR,"Fix SRD walls overlap but fix srd overlap not set"); } } @@ -335,7 +332,7 @@ void FixSRD::init() if (strcmp(modify->fix[i]->style,"deform") == 0) { FixDeform *deform = (FixDeform *) modify->fix[i]; if (deform->box_change_shape && deform->remapflag != V_REMAP) - error->all("Using fix srd with inconsistent " + error->all(FLERR,"Using fix srd with inconsistent " "fix deform remap option"); } } @@ -392,7 +389,7 @@ void FixSRD::setup(int vflag) setup_bounds(); if (dist_srd_reneigh < nevery*dt_big*vmax && me == 0) - error->warning("Fix srd SRD moves may trigger frequent reneighboring"); + error->warning(FLERR,"Fix srd SRD moves may trigger frequent reneighboring"); // setup search bins and search stencil based on these distances @@ -513,7 +510,7 @@ void FixSRD::pre_neighbor() if (ix < 0 || ix >= nbin2x || iy < 0 || iy >= nbin2y || iz < 0 || iz >= nbin2z) - error->one("Fix SRD: bad search bin assignment"); + error->one(FLERR,"Fix SRD: bad search bin assignment"); cutbinsq = biglist[nbig].cutbinsq; for (j = 0; j < nstencil; j++) { @@ -527,13 +524,13 @@ void FixSRD::pre_neighbor() atom->tag[i],i,x[i][0],x[i][1],x[i][2]); printf("Bin indices: %d %d %d, %d %d %d, %d %d %d\n", ix,iy,iz,jx,jy,jz,nbin2x,nbin2y,nbin2z); - error->one("Fix SRD: bad stencil bin for big particle"); + error->one(FLERR,"Fix SRD: bad stencil bin for big particle"); } rsq = point_bin_distance(x[i],jx,jy,jz); if (rsq < cutbinsq) { jbin = ibin + stencil[j][3]; if (nbinbig[jbin] == ATOMPERBIN) - error->one("Fix SRD: too many big particles in bin"); + error->one(FLERR,"Fix SRD: too many big particles in bin"); binbig[jbin][nbinbig[jbin]++] = nbig; } } @@ -562,12 +559,12 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-xblo2)*bininv2x); if (hi < 0) continue; - if (hi >= nbin2x) error->all("Fix SRD: bad search bin assignment"); + if (hi >= nbin2x) error->all(FLERR,"Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-xblo2)*bininv2x); if (lo >= nbin2x) continue; - if (lo < 0) error->all("Fix SRD: bad search bin assignment"); + if (lo < 0) error->all(FLERR,"Fix SRD: bad search bin assignment"); hi = nbin2x-1; } @@ -576,7 +573,7 @@ void FixSRD::pre_neighbor() for (iz = 0; iz < nbin2z; iz++) { ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix; if (nbinbig[ibin] == ATOMPERBIN) - error->all("Fix SRD: too many walls in bin"); + error->all(FLERR,"Fix SRD: too many walls in bin"); binbig[ibin][nbinbig[ibin]++] = nbig+m; } @@ -584,12 +581,12 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-yblo2)*bininv2y); if (hi < 0) continue; - if (hi >= nbin2y) error->all("Fix SRD: bad search bin assignment"); + if (hi >= nbin2y) error->all(FLERR,"Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-yblo2)*bininv2y); if (lo >= nbin2y) continue; - if (lo < 0) error->all("Fix SRD: bad search bin assignment"); + if (lo < 0) error->all(FLERR,"Fix SRD: bad search bin assignment"); hi = nbin2y-1; } @@ -598,7 +595,7 @@ void FixSRD::pre_neighbor() for (iz = 0; iz < nbin2z; iz++) { ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix; if (nbinbig[ibin] == ATOMPERBIN) - error->all("Fix SRD: too many walls in bin"); + error->all(FLERR,"Fix SRD: too many walls in bin"); binbig[ibin][nbinbig[ibin]++] = nbig+m; } @@ -606,12 +603,12 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-zblo2)*bininv2z); if (hi < 0) continue; - if (hi >= nbin2z) error->all("Fix SRD: bad search bin assignment"); + if (hi >= nbin2z) error->all(FLERR,"Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-zblo2)*bininv2z); if (lo >= nbin2z) continue; - if (lo < 0) error->all("Fix SRD: bad search bin assignment"); + if (lo < 0) error->all(FLERR,"Fix SRD: bad search bin assignment"); hi = nbin2z-1; } @@ -620,7 +617,7 @@ void FixSRD::pre_neighbor() for (iy = 0; iy < nbin2y; iy++) { ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix; if (nbinbig[ibin] == ATOMPERBIN) - error->all("Fix SRD: too many walls in bin"); + error->all(FLERR,"Fix SRD: too many walls in bin"); binbig[ibin][nbinbig[ibin]++] = nbig+m; } } @@ -696,7 +693,7 @@ void FixSRD::post_force(int vflag) fprintf(screen,"ix,iy,iz nx,ny,nz = %d %d %d %d %d %d\n", ix,iy,iz,nbin2x,nbin2y,nbin2z); } - error->one("Fix SRD: bad bin assignment for SRD advection"); + error->one(FLERR,"Fix SRD: bad bin assignment for SRD advection"); } } @@ -1155,8 +1152,8 @@ void FixSRD::collisions_single() "inside big particle %d on step " BIGINT_FORMAT " bounce %d\n", atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1); - if (insideflag == INSIDE_ERROR) error->one(str); - error->warning(str); + if (insideflag == INSIDE_ERROR) error->one(FLERR,str); + error->warning(FLERR,str); } break; } @@ -1294,8 +1291,8 @@ void FixSRD::collisions_multi() "inside big particle %d on step " BIGINT_FORMAT " bounce %d\n", atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1); - if (insideflag == INSIDE_ERROR) error->one(str); - error->warning(str); + if (insideflag == INSIDE_ERROR) error->one(FLERR,str); + error->warning(FLERR,str); } t_first = 0.0; break; @@ -2066,7 +2063,7 @@ int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew, xs[1] < srdlo[1] || xs[1] > srdhi[1] || xs[2] < srdlo[2] || xs[2] > srdhi[2]) { if (screen) { - error->warning("Fix srd particle moved outside valid domain"); + error->warning(FLERR,"Fix srd particle moved outside valid domain"); fprintf(screen," particle %d on proc %d at timestep " BIGINT_FORMAT, atom->tag[i],me,update->ntimestep); fprintf(screen," xnew %g %g %g\n",xs[0],xs[1],xs[2]); @@ -2127,7 +2124,7 @@ void FixSRD::parameterize() minbigdiam = MIN(minbigdiam,2.0*shape[1]); minbigdiam = MIN(minbigdiam,2.0*shape[2]); } else - error->one("Big particle in fix srd cannot be point particle"); + error->one(FLERR,"Big particle in fix srd cannot be point particle"); } double tmp = maxbigdiam; @@ -2169,7 +2166,7 @@ void FixSRD::parameterize() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); if (flagall) - error->all("Fix srd requires SRD particles all have same mass"); + error->all(FLERR,"Fix srd requires SRD particles all have same mass"); // set temperature and lamda of SRD particles from each other // lamda = dt_srd * sqrt(boltz * temperature_srd / mass_srd); @@ -2339,7 +2336,7 @@ void FixSRD::parameterize() if (nbin1x < comm->procgrid[0] || nbin1y < comm->procgrid[1] || nbin1z < comm->procgrid[2]) - error->all("Fewer SRD bins than processors in some dimension"); + error->all(FLERR,"Fewer SRD bins than processors in some dimension"); // check if SRD bins are within tolerance for shape and size @@ -2353,9 +2350,9 @@ void FixSRD::parameterize() if (tolflag) { if (cubicflag == CUBIC_ERROR) - error->all("SRD bins for fix srd are not cubic enough"); + error->all(FLERR,"SRD bins for fix srd are not cubic enough"); if (me == 0) - error->warning("SRD bins for fix srd are not cubic enough"); + error->warning(FLERR,"SRD bins for fix srd are not cubic enough"); } tolflag = 0; @@ -2370,9 +2367,9 @@ void FixSRD::parameterize() if (tolflag) { if (cubicflag == CUBIC_ERROR) - error->all("SRD bin size for fix srd differs from user request"); + error->all(FLERR,"SRD bin size for fix srd differs from user request"); if (me == 0) - error->warning("SRD bin size for fix srd differs from user request"); + error->warning(FLERR,"SRD bin size for fix srd differs from user request"); } // error if lamda < 0.6 of SRD grid size and no shifting allowed @@ -2383,21 +2380,21 @@ void FixSRD::parameterize() shiftflag = 0; if (lamda < 0.6*maxgridsrd && shiftuser == SHIFT_NO) - error->all("Fix srd lamda must be >= 0.6 of SRD grid size"); + error->all(FLERR,"Fix srd lamda must be >= 0.6 of SRD grid size"); else if (lamda < 0.6*maxgridsrd && shiftuser == SHIFT_POSSIBLE) { shiftflag = 1; if (me == 0) - error->warning("SRD bin shifting turned on due to small lamda"); + error->warning(FLERR,"SRD bin shifting turned on due to small lamda"); } else if (shiftuser == SHIFT_YES) shiftflag = 1; // warnings if (bigexist && maxgridsrd > 0.25 * minbigdiam && me == 0) - error->warning("Fix srd grid size > 1/4 of big particle diameter"); + error->warning(FLERR,"Fix srd grid size > 1/4 of big particle diameter"); if (viscosity < 0.0 && me == 0) - error->warning("Fix srd viscosity < 0.0 due to low SRD density"); + error->warning(FLERR,"Fix srd viscosity < 0.0 due to low SRD density"); if (bigexist && dt_big*vmax > minbigdiam && me == 0) - error->warning("Fix srd particles may move > big particle diameter"); + error->warning(FLERR,"Fix srd particles may move > big particle diameter"); } /* ---------------------------------------------------------------------- diff --git a/src/SRD/fix_wall_srd.cpp b/src/SRD/fix_wall_srd.cpp index 2f18d28837..fe38da8b4e 100644 --- a/src/SRD/fix_wall_srd.cpp +++ b/src/SRD/fix_wall_srd.cpp @@ -36,7 +36,7 @@ enum{NONE,EDGE,CONSTANT,VARIABLE}; FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix wall/srd command"); + if (narg < 4) error->all(FLERR,"Illegal fix wall/srd command"); // parse args @@ -48,7 +48,7 @@ FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) : if ((strcmp(arg[iarg],"xlo") == 0) || (strcmp(arg[iarg],"xhi") == 0) || (strcmp(arg[iarg],"ylo") == 0) || (strcmp(arg[iarg],"yhi") == 0) || (strcmp(arg[iarg],"zlo") == 0) || (strcmp(arg[iarg],"zhi") == 0)) { - if (iarg+2 > narg) error->all("Illegal fix wall/srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall/srd command"); int newwall; if (strcmp(arg[iarg],"xlo") == 0) newwall = XLO; @@ -60,7 +60,7 @@ FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) : for (int m = 0; m < nwall; m++) if (newwall == wallwhich[m]) - error->all("Wall defined twice in fix wall/srd command"); + error->all(FLERR,"Wall defined twice in fix wall/srd command"); wallwhich[nwall] = newwall; if (strcmp(arg[iarg+1],"EDGE") == 0) { @@ -83,30 +83,30 @@ FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal wall/srd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal wall/srd command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix wall/srd command"); + else error->all(FLERR,"Illegal fix wall/srd command"); iarg += 2; - } else error->all("Illegal fix wall/srd command"); + } else error->all(FLERR,"Illegal fix wall/srd command"); } // error check - if (nwall == 0) error->all("Illegal fix wall command"); + if (nwall == 0) error->all(FLERR,"Illegal fix wall command"); for (int m = 0; m < nwall; m++) { if ((wallwhich[m] == XLO || wallwhich[m] == XHI) && domain->xperiodic) - error->all("Cannot use fix wall/srd in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/srd in periodic dimension"); if ((wallwhich[m] == YLO || wallwhich[m] == YHI) && domain->yperiodic) - error->all("Cannot use fix wall/srd in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/srd in periodic dimension"); if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->zperiodic) - error->all("Cannot use fix wall/srd in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/srd in periodic dimension"); } for (int m = 0; m < nwall; m++) if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->dimension == 2) - error->all("Cannot use fix wall/srd zlo/zhi for a 2d simulation"); + error->all(FLERR,"Cannot use fix wall/srd zlo/zhi for a 2d simulation"); // setup wall force array @@ -127,7 +127,7 @@ FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) : if (flag) { if (scaleflag && domain->lattice == NULL) - error->all("Use of fix wall with undefined lattice"); + error->all(FLERR,"Use of fix wall with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -188,15 +188,15 @@ void FixWallSRD::init() int flag = 0; for (int m = 0; m < modify->nfix; m++) if (strcmp(modify->fix[m]->style,"srd") == 0) flag = 1; - if (!flag) error->all("Cannot use fix wall/srd without fix srd"); + if (!flag) error->all(FLERR,"Cannot use fix wall/srd without fix srd"); for (int m = 0; m < nwall; m++) { if (wallstyle[m] != VARIABLE) continue; varindex[m] = input->variable->find(varstr[m]); if (varindex[m] < 0) - error->all("Variable name for fix wall/srd does not exist"); + error->all(FLERR,"Variable name for fix wall/srd does not exist"); if (!input->variable->equalstyle(varindex[m])) - error->all("Variable for fix wall/srd is invalid style"); + error->all(FLERR,"Variable for fix wall/srd is invalid style"); } dt = update->dt; diff --git a/src/USER-ATC/fix_atc.cpp b/src/USER-ATC/fix_atc.cpp index 976b053679..dde062dc40 100644 --- a/src/USER-ATC/fix_atc.cpp +++ b/src/USER-ATC/fix_atc.cpp @@ -47,7 +47,7 @@ FixATC::FixATC(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { // ID GROUP atc PHYSICSTYPE [PARAMETERFILE] // can have either 4 or 5 args, only arg[3] and arg[4] are used by this class - if (narg > 5 || narg < 4) lmp->error->all("Illegal fix atc command"); + if (narg > 5 || narg < 4) lmp->error->all(FLERR,"Illegal fix atc command"); // Set LAMMPS pointer on LammpsInterface ATC::LammpsInterface::instance()->set_lammps(lmp); @@ -240,7 +240,7 @@ FixATC::FixATC(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } else { - lmp->error->all("Unknown physics type in ATC"); + lmp->error->all(FLERR,"Unknown physics type in ATC"); } } catch (ATC::ATC_Error& atcError) { diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp index dd4a0657f8..5c9e789bf0 100644 --- a/src/USER-AWPMD/atom_vec_wavepacket.cpp +++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp @@ -896,17 +896,17 @@ void AtomVecWavepacket::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file (ID tag must be >0)"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file (ID tag must be >0)"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[2]); spin[nlocal] = atoi(values[3]); eradius[nlocal] = atof(values[4]); if (eradius[nlocal] < 0.0) - error->one("Invalid eradius in Atoms section of data file"); + error->one(FLERR,"Invalid eradius in Atoms section of data file"); etag[nlocal] = atoi(values[5]); @@ -940,7 +940,7 @@ int AtomVecWavepacket::data_atom_hybrid(int nlocal, char **values) spin[nlocal] = atoi(values[1]); eradius[nlocal] = atof(values[2]); if (eradius[nlocal] < 0.0) - error->one("Invalid eradius in Atoms section of data file"); + error->one(FLERR,"Invalid eradius in Atoms section of data file"); etag[nlocal] = atoi(values[3]); cs[2*nlocal] = atoi(values[4]); diff --git a/src/USER-AWPMD/fix_nve_awpmd.cpp b/src/USER-AWPMD/fix_nve_awpmd.cpp index 418b942ecd..5aee8958ae 100644 --- a/src/USER-AWPMD/fix_nve_awpmd.cpp +++ b/src/USER-AWPMD/fix_nve_awpmd.cpp @@ -36,9 +36,9 @@ FixNVEAwpmd::FixNVEAwpmd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (!atom->wavepacket_flag) - error->all("Fix nve/awpmd requires atom style wavepacket"); + error->all(FLERR,"Fix nve/awpmd requires atom style wavepacket"); //if (!atom->mass_type != 1) - // error->all("Fix nve/awpmd requires per type mass"); + // error->all(FLERR,"Fix nve/awpmd requires per type mass"); time_integrate = 1; } diff --git a/src/USER-AWPMD/pair_awpmd_cut.cpp b/src/USER-AWPMD/pair_awpmd_cut.cpp index ae276334bb..4644f1a2ce 100644 --- a/src/USER-AWPMD/pair_awpmd_cut.cpp +++ b/src/USER-AWPMD/pair_awpmd_cut.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairAWPMDCut::PairAWPMDCut(LAMMPS *lmp) : Pair(lmp) @@ -241,7 +238,7 @@ void PairAWPMDCut::compute(int eflag, int vflag) etmap[etag[i]].push_back(i); } else - error->all(fmt("Invalid spin value (%d) for particle %d !",spin[i],i)); + error->all(FLERR,fmt("Invalid spin value (%d) for particle %d !",spin[i],i)); } // ion force vector Vector_3 *fi=NULL; @@ -258,7 +255,7 @@ void PairAWPMDCut::compute(int eflag, int vflag) for(size_t k=0;kall(fmt("WP splits for one electron should have the same spin (at particles %d, %d)!",el[0],i)); + error->all(FLERR,fmt("WP splits for one electron should have the same spin (at particles %d, %d)!",el[0],i)); double m= atom->mass ? atom->mass[type[i]] : force->e_mass; Vector_3 xx=Vector_3(x[i][0],x[i][1],x[i][2]); Vector_3 rv=m*Vector_3(v[i][0],v[i][1],v[i][2]); @@ -411,7 +408,7 @@ void PairAWPMDCut::allocate() // -1 for length means default setting (L/2 for cutoff and L for width PBC) void PairAWPMDCut::settings(int narg, char **arg){ - if (narg < 1) error->all("Illegal pair_style command"); + if (narg < 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -432,21 +429,21 @@ void PairAWPMDCut::settings(int narg, char **arg){ wpmd->constraint=AWPMD::FIX; i++; if(i>=narg) - error->all("Setting 'fix' should be followed by a number in awpmd/cut"); + error->all(FLERR,"Setting 'fix' should be followed by a number in awpmd/cut"); wpmd->w0=force->numeric(arg[i]); } else if(!strcmp(arg[i],"harm")){ wpmd->constraint=AWPMD::HARM; i++; if(i>=narg) - error->all("Setting 'harm' should be followed by a number in awpmd/cut"); + error->all(FLERR,"Setting 'harm' should be followed by a number in awpmd/cut"); wpmd->w0=force->numeric(arg[i]); wpmd->set_harm_constr(wpmd->w0); } else if(!strcmp(arg[i],"pbc")){ i++; if(i>=narg) - error->all("Setting 'pbc' should be followed by a number in awpmd/cut"); + error->all(FLERR,"Setting 'pbc' should be followed by a number in awpmd/cut"); width_pbc=force->numeric(arg[i]); } else if(!strcmp(arg[i],"relax")) @@ -454,7 +451,7 @@ void PairAWPMDCut::settings(int narg, char **arg){ else if(!strcmp(arg[i],"ermscale")){ i++; if(i>=narg) - error->all("Setting 'ermscale' should be followed by a number in awpmd/cut"); + error->all(FLERR,"Setting 'ermscale' should be followed by a number in awpmd/cut"); ermscale=force->numeric(arg[i]); } else if(!strcmp(arg[i],"flex_press")) @@ -478,7 +475,7 @@ void PairAWPMDCut::settings(int narg, char **arg){ // pair settings are as usual void PairAWPMDCut::coeff(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all("Incorrect args for pair coefficients"); + if (narg < 2 || narg > 3) error->all(FLERR,"Incorrect args for pair coefficients"); /*if(domain->xperiodic == 1 || domain->yperiodic == 1 || domain->zperiodic == 1) {*/ @@ -515,7 +512,7 @@ void PairAWPMDCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -528,13 +525,13 @@ void PairAWPMDCut::init_style() if (!atom->q_flag || !atom->spin_flag || !atom->eradius_flag || !atom->erforce_flag ) // TO DO: adjust this to match approximation used - error->all("Pair awpmd/cut requires atom attributes " + error->all(FLERR,"Pair awpmd/cut requires atom attributes " "q, spin, eradius, erforce"); /* if(vflag_atom){ // can't compute virial per atom //warning-> - error->all("Pair style awpmd can't compute per atom virials"); + error->all(FLERR,"Pair style awpmd can't compute per atom virials"); }*/ // add hook to minimizer for eradius and erforce @@ -546,7 +543,7 @@ void PairAWPMDCut::init_style() /*if (update->whichflag == 1) { if (force->qqr2e == 332.06371 && update->dt == 1.0) - error->all("You must lower the default real units timestep for pEFF "); + error->all(FLERR,"You must lower the default real units timestep for pEFF "); }*/ // need a half neigh list and optionally a granular history neigh list @@ -554,19 +551,19 @@ void PairAWPMDCut::init_style() //int irequest = neighbor->request(this); //if (atom->tag_enable == 0) - // error->all("Pair style reax requires atom IDs"); + // error->all(FLERR,"Pair style reax requires atom IDs"); //if (force->newton_pair == 0) - //error->all("Pair style awpmd requires newton pair on"); + //error->all(FLERR,"Pair style awpmd requires newton pair on"); //if (strcmp(update->unit_style,"real") != 0 && comm->me == 0) - //error->warning("Not using real units with pair reax"); + //error->warning(FLERR,"Not using real units with pair reax"); int irequest = neighbor->request(this); neighbor->requests[irequest]->newton = 2; if(force->e_mass==0. || force->hhmrr2e==0. || force->mvh2r==0.) - error->all("Pair style awpmd requires e_mass and conversions hhmrr2e, mvh2r to be properly set for unit system"); + error->all(FLERR,"Pair style awpmd requires e_mass and conversions hhmrr2e, mvh2r to be properly set for unit system"); wpmd->me=force->e_mass; wpmd->h2_me=force->hhmrr2e/force->e_mass; diff --git a/src/USER-CG-CMM/angle_cg_cmm.cpp b/src/USER-CG-CMM/angle_cg_cmm.cpp index a818b061f1..7d9800808a 100644 --- a/src/USER-CG-CMM/angle_cg_cmm.cpp +++ b/src/USER-CG-CMM/angle_cg_cmm.cpp @@ -297,7 +297,7 @@ void AngleCGCMM::allocate() void AngleCGCMM::coeff(int narg, char **arg) { - if (narg != 6) error->all("Incorrect args for angle coefficients"); + if (narg != 6) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -307,7 +307,7 @@ void AngleCGCMM::coeff(int narg, char **arg) double theta0_one = atof(arg[2]); int cg_type_one=find_cg_type(arg[3]); - if (cg_type_one == CG_NOT_SET) error->all("Error reading CG type flag."); + if (cg_type_one == CG_NOT_SET) error->all(FLERR,"Error reading CG type flag."); double epsilon_one = atof(arg[4]); double sigma_one = atof(arg[5]); @@ -332,7 +332,7 @@ void AngleCGCMM::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-CG-CMM/pair_cg_cmm_coul_cut.cpp b/src/USER-CG-CMM/pair_cg_cmm_coul_cut.cpp index 7b270b351c..10cee8919b 100644 --- a/src/USER-CG-CMM/pair_cg_cmm_coul_cut.cpp +++ b/src/USER-CG-CMM/pair_cg_cmm_coul_cut.cpp @@ -16,17 +16,12 @@ Contributing author: Axel Kohlmeyer ------------------------------------------------------------------------- */ +#include "string.h" #include "pair_cg_cmm_coul_cut.h" #include "memory.h" #include "atom.h" -#include "string.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ PairCGCMMCoulCut::PairCGCMMCoulCut(LAMMPS *lmp) : PairCMMCommon(lmp) { @@ -67,7 +62,7 @@ void PairCGCMMCoulCut::allocate() void PairCGCMMCoulCut::init_style() { if (!atom->q_flag) - error->all("Pair style cg/cut/coul/cut requires atom attribute q"); + error->all(FLERR,"Pair style cg/cut/coul/cut requires atom attribute q"); PairCMMCommon::init_style(); @@ -88,7 +83,7 @@ double PairCGCMMCoulCut::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && MIN(cut_lj[i][j],cut_coul[i][j]) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); return mycut; } diff --git a/src/USER-CG-CMM/pair_cg_cmm_coul_long.cpp b/src/USER-CG-CMM/pair_cg_cmm_coul_long.cpp index 2947b3ce64..fa7769927a 100644 --- a/src/USER-CG-CMM/pair_cg_cmm_coul_long.cpp +++ b/src/USER-CG-CMM/pair_cg_cmm_coul_long.cpp @@ -16,19 +16,17 @@ Contributing author: Axel Kohlmeyer ------------------------------------------------------------------------- */ +#include "string.h" #include "pair_cg_cmm_coul_long.h" #include "memory.h" #include "atom.h" #include "force.h" #include "kspace.h" -#include "string.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define EWALD_F 1.12837917 - using namespace LAMMPS_NS; +#define EWALD_F 1.12837917 + /* ---------------------------------------------------------------------- */ PairCGCMMCoulLong::PairCGCMMCoulLong(LAMMPS *lmp) : PairCMMCommon(lmp) @@ -91,7 +89,7 @@ void PairCGCMMCoulLong::free_tables() void PairCGCMMCoulLong::init_style() { if (!atom->q_flag) - error->all("Pair style cg/cut/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style cg/cut/coul/long requires atom attribute q"); PairCMMCommon::init_style(); @@ -105,7 +103,7 @@ void PairCGCMMCoulLong::init_style() // ensure use of KSpace long-range solver, set g_ewald if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables @@ -122,7 +120,7 @@ double PairCGCMMCoulLong::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && MIN(cut_lj[i][j],cut_coul_global) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); return mycut; } diff --git a/src/USER-CG-CMM/pair_cmm_common.cpp b/src/USER-CG-CMM/pair_cmm_common.cpp index 043716e9f0..81d142f568 100644 --- a/src/USER-CG-CMM/pair_cmm_common.cpp +++ b/src/USER-CG-CMM/pair_cmm_common.cpp @@ -26,7 +26,6 @@ using namespace LAMMPS_NS; -#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define SMALL 1.0e-6 /* ---------------------------------------------------------------------- */ @@ -102,7 +101,7 @@ void PairCMMCommon::allocate() // args = cutoff (cutoff2 (kappa)) void PairCMMCommon::settings(int narg, char **arg) { - if ((narg < 1) || (narg > 3)) error->all("Illegal pair_style command"); + if ((narg < 1) || (narg > 3)) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -137,7 +136,7 @@ void PairCMMCommon::settings(int narg, char **arg) void PairCMMCommon::coeff(int narg, char **arg) { - if (narg < 5 || narg > 7) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 7) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -145,7 +144,7 @@ void PairCMMCommon::coeff(int narg, char **arg) force->bounds(arg[1],atom->ntypes,jlo,jhi); int cg_type_one=find_cg_type(arg[2]); - if (cg_type_one == CG_NOT_SET) error->all("Error reading CG type flag."); + if (cg_type_one == CG_NOT_SET) error->all(FLERR,"Error reading CG type flag."); double epsilon_one = force->numeric(arg[3]); double sigma_one = force->numeric(arg[4]); @@ -174,7 +173,7 @@ void PairCMMCommon::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -240,13 +239,13 @@ void PairCMMCommon::init_list(int id, NeighList *ptr) double PairCMMCommon::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("for CG styles, epsilon and sigma need to be set explicitly for all pairs."); + error->all(FLERR,"for CG styles, epsilon and sigma need to be set explicitly for all pairs."); } const int cgt = cg_type[i][j]; if (cgt == CG_NOT_SET) - error->all("unrecognized LJ parameter flag"); + error->all(FLERR,"unrecognized LJ parameter flag"); lj1[i][j] = cg_prefact[cgt] * cg_pow1[cgt] * epsilon[i][j] * pow(sigma[i][j],cg_pow1[cgt]); lj2[i][j] = cg_prefact[cgt] * cg_pow2[cgt] * epsilon[i][j] * pow(sigma[i][j],cg_pow2[cgt]); @@ -290,7 +289,7 @@ double PairCMMCommon::init_one(int i, int j) // count total # of atoms of type I and J via Allreduce if (tail_flag) { #if 1 - error->all("tail correction not (yet) supported by CG potentials."); + error->all(FLERR,"tail correction not (yet) supported by CG potentials."); #else int *type = atom->type; int nlocal = atom->nlocal; @@ -456,18 +455,18 @@ double PairCMMCommon::eval_single(int coul_type, int i, int j, int itype, int jt if (rsq < cut_coul[itype][jtype]) { if(coul_type == CG_COUL_LONG) { - error->all("single energy computation with long-range coulomb not supported by CG potentials."); + error->all(FLERR,"single energy computation with long-range coulomb not supported by CG potentials."); } else if ((coul_type == CG_COUL_CUT) || (coul_type == CG_COUL_DEBYE)) { const double r2inv = 1.0/rsq; const double rinv = sqrt(r2inv); const double qscreen=exp(-kappa*sqrt(rsq)); coul_force = force->qqrd2e * atom->q[i]*atom->q[j]*rinv * qscreen * (kappa + rinv); coul_erg = force->qqrd2e * atom->q[i]*atom->q[j]*rinv * qscreen; - // error->all("single energy computation with coulomb not supported by CG potentials."); + // error->all(FLERR,"single energy computation with coulomb not supported by CG potentials."); } else if (coul_type == CG_COUL_NONE) { ; // do nothing } else { - error->all("unknown coulomb type with CG potentials."); + error->all(FLERR,"unknown coulomb type with CG potentials."); } } diff --git a/src/USER-CUDA/atom_vec_angle_cuda.cpp b/src/USER-CUDA/atom_vec_angle_cuda.cpp index 323a1bedf6..b816b690b1 100644 --- a/src/USER-CUDA/atom_vec_angle_cuda.cpp +++ b/src/USER-CUDA/atom_vec_angle_cuda.cpp @@ -65,7 +65,7 @@ AtomVecAngleCuda::AtomVecAngleCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); maxsend=0; cudable=true; diff --git a/src/USER-CUDA/atom_vec_atomic_cuda.cpp b/src/USER-CUDA/atom_vec_atomic_cuda.cpp index c57e0654f6..b6bb14422c 100644 --- a/src/USER-CUDA/atom_vec_atomic_cuda.cpp +++ b/src/USER-CUDA/atom_vec_atomic_cuda.cpp @@ -65,7 +65,7 @@ AtomVecAtomicCuda::AtomVecAtomicCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); maxsend=0; cudable=true; diff --git a/src/USER-CUDA/atom_vec_charge_cuda.cpp b/src/USER-CUDA/atom_vec_charge_cuda.cpp index e057253604..a15836c45b 100644 --- a/src/USER-CUDA/atom_vec_charge_cuda.cpp +++ b/src/USER-CUDA/atom_vec_charge_cuda.cpp @@ -64,7 +64,7 @@ AtomVecChargeCuda::AtomVecChargeCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); maxsend=0; cudable=true; diff --git a/src/USER-CUDA/atom_vec_full_cuda.cpp b/src/USER-CUDA/atom_vec_full_cuda.cpp index f010181ced..9e656ed58d 100644 --- a/src/USER-CUDA/atom_vec_full_cuda.cpp +++ b/src/USER-CUDA/atom_vec_full_cuda.cpp @@ -65,7 +65,7 @@ AtomVecFullCuda::AtomVecFullCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); maxsend=0; cudable=true; diff --git a/src/USER-CUDA/comm_cuda.cpp b/src/USER-CUDA/comm_cuda.cpp index 4a7a822ae0..8e75f93ba5 100644 --- a/src/USER-CUDA/comm_cuda.cpp +++ b/src/USER-CUDA/comm_cuda.cpp @@ -41,9 +41,6 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 #define BUFMIN 1000 #define BUFEXTRA 1000 - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define BIG 1.0e20 enum{SINGLE,MULTI}; @@ -56,7 +53,7 @@ CommCuda::CommCuda(LAMMPS *lmp):Comm(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); cu_pbc=NULL; cu_slablo=NULL; @@ -279,7 +276,7 @@ cuda->shared_data.cuda_timings.comm_forward_mpi_lower+= if (sendnum[iswap]) { n = Cuda_CommCuda_PackComm_Self(&cuda->shared_data,sendnum[iswap],iswap,firstrecv[iswap],pbc[iswap],pbc_flag[iswap]); - if(n<0) error->all(" # CUDA ERRROR on PackComm_Self"); + if(n<0) error->all(FLERR," # CUDA ERRROR on PackComm_Self"); if((sizeof(X_FLOAT)!=sizeof(double)) && n) n=(n+1)*sizeof(X_FLOAT)/sizeof(double); } @@ -382,7 +379,7 @@ clock_gettime(CLOCK_REALTIME,&time2); if (sendnum[iswap]) { n = Cuda_CommCuda_PackComm_Self(&cuda->shared_data,sendnum[iswap],iswap,firstrecv[iswap],pbc[iswap],pbc_flag[iswap]); - if(n<0) error->all(" # CUDA ERRROR on PackComm_Self"); + if(n<0) error->all(FLERR," # CUDA ERRROR on PackComm_Self"); if((sizeof(X_FLOAT)!=sizeof(double)) && n) n=(n+1)*sizeof(X_FLOAT)/sizeof(double); } diff --git a/src/USER-CUDA/compute_pressure_cuda.cpp b/src/USER-CUDA/compute_pressure_cuda.cpp index aceb06a36d..27de7e5850 100644 --- a/src/USER-CUDA/compute_pressure_cuda.cpp +++ b/src/USER-CUDA/compute_pressure_cuda.cpp @@ -64,7 +64,7 @@ ComputePressureCuda::ComputePressureCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); cudable = 1; // store temperature ID used by pressure computation @@ -78,7 +78,7 @@ ComputePressureCuda::ComputePressureCuda(LAMMPS *lmp, int narg, char **arg) : delete [] id_temp; if (modify->compute[icompute]->cudable == 0) { - error->warning("Compute pressure/cuda temperature ID is not cudable! Try a temp/cuda style."); + error->warning(FLERR,"Compute pressure/cuda temperature ID is not cudable! Try a temp/cuda style."); cudable = 0; } @@ -87,7 +87,7 @@ ComputePressureCuda::ComputePressureCuda(LAMMPS *lmp, int narg, char **arg) : double ComputePressureCuda::compute_scalar() { if(not temperature->cudable && cuda->finished_setup) cuda->downloadAll(); - ComputePressure::compute_scalar(); + return ComputePressure::compute_scalar(); } void ComputePressureCuda::compute_vector() diff --git a/src/USER-CUDA/compute_temp_cuda.cpp b/src/USER-CUDA/compute_temp_cuda.cpp index 0e13f67c14..0b560f5366 100644 --- a/src/USER-CUDA/compute_temp_cuda.cpp +++ b/src/USER-CUDA/compute_temp_cuda.cpp @@ -59,9 +59,9 @@ ComputeTempCuda::ComputeTempCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 3) error->all("Illegal compute temp/cuda command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp/cuda command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -158,7 +158,7 @@ double ComputeTempCuda::compute_scalar() for(int i=0;inlocal;i++) if((v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2])>1e5) printf("%i %i // %lf %lf %lf // %lf %lf %lf\n",atom->tag[i],atom->type[i],x[i][0], x[i][1], x[i][2],v[i][0], v[i][1], v[i][2]); - error->all("Temperature out of range. Simulations will be abortet.\n"); + error->all(FLERR,"Temperature out of range. Simulations will be abortet.\n"); } return scalar; } diff --git a/src/USER-CUDA/compute_temp_partial_cuda.cpp b/src/USER-CUDA/compute_temp_partial_cuda.cpp index c9a126a18d..e39484c835 100644 --- a/src/USER-CUDA/compute_temp_partial_cuda.cpp +++ b/src/USER-CUDA/compute_temp_partial_cuda.cpp @@ -60,9 +60,9 @@ ComputeTempPartialCuda::ComputeTempPartialCuda(LAMMPS *lmp, int narg, char **arg { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 6) error->all("Illegal compute temp/partial command"); + if (narg != 6) error->all(FLERR,"Illegal compute temp/partial command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -75,7 +75,7 @@ ComputeTempPartialCuda::ComputeTempPartialCuda(LAMMPS *lmp, int narg, char **arg yflag = atoi(arg[4]); zflag = atoi(arg[5]); if (zflag && domain->dimension == 2) - error->all("Compute temp/partial cannot use vz for 2d systemx"); + error->all(FLERR,"Compute temp/partial cannot use vz for 2d systemx"); maxbias = 0; vbiasall = NULL; @@ -181,7 +181,7 @@ double ComputeTempPartialCuda::compute_scalar() for(int i=0;inlocal;i++) if((v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2])>1e5) printf("%i %i // %lf %lf %lf // %lf %lf %lf\n",atom->tag[i],atom->type[i],x[i][0], x[i][1], x[i][2],v[i][0], v[i][1], v[i][2]); - error->all("Temperature out of range. Simulations will be abortet.\n"); + error->all(FLERR,"Temperature out of range. Simulations will be abortet.\n"); } return scalar; } diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp index 66273775e7..39261bd7c0 100644 --- a/src/USER-CUDA/cuda.cpp +++ b/src/USER-CUDA/cuda.cpp @@ -46,8 +46,6 @@ using namespace LAMMPS_NS; -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp) { cuda_exists=true; @@ -198,15 +196,15 @@ void Cuda::accelerator(int narg, char** arg) if(strcmp(arg[i],"gpu/node")==0) { if(++i==narg) - error->all("Invalid Options for 'accelerator' command. Expecting a number or keyword 'special' after 'gpu/node' option."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number or keyword 'special' after 'gpu/node' option."); if(strcmp(arg[i],"special")==0) { if(++i==narg) - error->all("Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'."); pppn=atoi(arg[i]); - if(pppn<1) error->all("Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'."); + if(pppn<1) error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'."); if(i+pppn==narg) - error->all("Invalid Options for 'accelerator' command. Expecting list of device ids after keyword 'gpu/node special'."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting list of device ids after keyword 'gpu/node special'."); devicelist=new int[pppn]; for(int k=0;kall("Invalid Options for 'accelerator' command. Expecting a number after 'pinned' option."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'pinned' option."); pinned=atoi(arg[i])==0?false:true; if((pinned==false)&&(universe->me==0)) printf(" #CUDA: Pinned memory is not used for communication\n"); } @@ -229,7 +227,7 @@ void Cuda::accelerator(int narg, char** arg) if(strcmp(arg[i],"suffix")==0) { if(++i==narg) - error->all("Invalid Options for 'accelerator' command. Expecting a string after 'suffix' option."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a string after 'suffix' option."); strcpy(lmp->suffix,arg[i]); } if(strcmp(arg[i],"overlap_comm")==0) @@ -239,14 +237,14 @@ void Cuda::accelerator(int narg, char** arg) if(strcmp(arg[i],"dotest")==0) { if(++i==narg) - error->all("Invalid Options for 'accelerator' command. Expecting a number after 'dotest' option."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'dotest' option."); testatom=atof(arg[i]); dotestatom=true; } if(strcmp(arg[i],"override_bpa")==0) { if(++i==narg) - error->all("Invalid Options for 'accelerator' command. Expecting a number after 'override_bpa' option."); + error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'override_bpa' option."); shared_data.pair.override_block_per_atom = atoi(arg[i]); } } diff --git a/src/USER-CUDA/cuda_neigh_list.cpp b/src/USER-CUDA/cuda_neigh_list.cpp index 9a88797e87..ef9edf5ef3 100644 --- a/src/USER-CUDA/cuda_neigh_list.cpp +++ b/src/USER-CUDA/cuda_neigh_list.cpp @@ -37,7 +37,7 @@ CudaNeighList::CudaNeighList(LAMMPS *lmp, class NeighList* neigh_list) : Pointer { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); MYDBG(printf("# CUDA: CudaNeighList::cudaNeighList() ... start\n");) this->neigh_list = neigh_list; diff --git a/src/USER-CUDA/domain_cuda.cpp b/src/USER-CUDA/domain_cuda.cpp index 37aa38c198..b241b16a29 100644 --- a/src/USER-CUDA/domain_cuda.cpp +++ b/src/USER-CUDA/domain_cuda.cpp @@ -42,8 +42,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 #define SMALL 1.0e-4 #define DELTA 1 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp @@ -55,7 +53,7 @@ DomainCuda::DomainCuda(LAMMPS *lmp) : Domain(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); } /* ---------------------------------------------------------------------- */ @@ -180,21 +178,21 @@ void DomainCuda::reset_box() else if (boundary[0][0] == 3) boxlo[0] = MIN(-all[0][0]-SMALL,minxlo); if (boundary[0][1] == 2) boxhi[0] = all[0][1] + SMALL; else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+SMALL,minxhi); - if (boxlo[0] > boxhi[0]) error->all("Illegal simulation box"); + if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box"); } if (yperiodic == 0) { if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - SMALL; else if (boundary[1][0] == 3) boxlo[1] = MIN(-all[1][0]-SMALL,minylo); if (boundary[1][1] == 2) boxhi[1] = all[1][1] + SMALL; else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+SMALL,minyhi); - if (boxlo[1] > boxhi[1]) error->all("Illegal simulation box"); + if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box"); } if (zperiodic == 0) { if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - SMALL; else if (boundary[2][0] == 3) boxlo[2] = MIN(-all[2][0]-SMALL,minzlo); if (boundary[2][1] == 2) boxhi[2] = all[2][1] + SMALL; else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+SMALL,minzhi); - if (boxlo[2] > boxhi[2]) error->all("Illegal simulation box"); + if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box"); } } diff --git a/src/USER-CUDA/fft3d_cuda.cpp b/src/USER-CUDA/fft3d_cuda.cpp index bb1278bb75..c6882f4597 100644 --- a/src/USER-CUDA/fft3d_cuda.cpp +++ b/src/USER-CUDA/fft3d_cuda.cpp @@ -50,6 +50,7 @@ #ifdef FFT_CUFFT #endif + #define MIN(A,B) ((A) < (B)) ? (A) : (B) #define MAX(A,B) ((A) > (B)) ? (A) : (B) @@ -182,7 +183,7 @@ struct fft_plan_3d *fft_3d_create_plan_cuda( MPI_Comm_size(comm,&nprocs); #ifndef FFT_CUFFT - error->all("ERROR: Trying to use cuda fft without FFT_CUFFT set. Recompile with make option 'cufft=1'."); + error->all(FLERR,"ERROR: Trying to use cuda fft without FFT_CUFFT set. Recompile with make option 'cufft=1'."); #endif // compute division of procs in 2 dimensions not on-processor bifactor_cuda(nprocs,&np1,&np2); diff --git a/src/USER-CUDA/fft3d_wrap_cuda.cpp b/src/USER-CUDA/fft3d_wrap_cuda.cpp index 5fa45bd85c..eab2f82e79 100644 --- a/src/USER-CUDA/fft3d_wrap_cuda.cpp +++ b/src/USER-CUDA/fft3d_wrap_cuda.cpp @@ -61,7 +61,7 @@ FFT3dCuda::FFT3dCuda(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, scaled,permute,nbuf); #endif - if (plan == NULL) error->one("Could not create 3d FFT plan"); + if (plan == NULL) error->one(FLERR,"Could not create 3d FFT plan"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-CUDA/fix_addforce_cuda.cpp b/src/USER-CUDA/fix_addforce_cuda.cpp index acf4d6d7ec..218110acf7 100644 --- a/src/USER-CUDA/fix_addforce_cuda.cpp +++ b/src/USER-CUDA/fix_addforce_cuda.cpp @@ -45,9 +45,9 @@ FixAddForceCuda::FixAddForceCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg < 6) error->all("Illegal fix addforce/cuda command"); + if (narg < 6) error->all(FLERR,"Illegal fix addforce/cuda command"); scalar_flag = 1; vector_flag = 1; @@ -67,14 +67,14 @@ FixAddForceCuda::FixAddForceCuda(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix addforce/cuda command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix addforce/cuda command"); iregion = domain->find_region(arg[iarg+1]); - if (iregion == -1) error->all("Fix addforce/cuda region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Fix addforce/cuda region ID does not exist"); iarg += 2; - } else error->all("Illegal fix addforce/cuda command"); + } else error->all(FLERR,"Illegal fix addforce/cuda command"); } - if(iregion!=-1) error->all("Error: fix addforce/cuda does not currently support 'region' option"); + if(iregion!=-1) error->all(FLERR,"Error: fix addforce/cuda does not currently support 'region' option"); force_flag = 0; foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0; diff --git a/src/USER-CUDA/fix_aveforce_cuda.cpp b/src/USER-CUDA/fix_aveforce_cuda.cpp index 10b4555e86..3a80fc1b3c 100644 --- a/src/USER-CUDA/fix_aveforce_cuda.cpp +++ b/src/USER-CUDA/fix_aveforce_cuda.cpp @@ -44,9 +44,9 @@ FixAveForceCuda::FixAveForceCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 6) error->all("Illegal fix aveforce command"); + if (narg != 6) error->all(FLERR,"Illegal fix aveforce command"); vector_flag = 1; size_vector = 3; @@ -68,15 +68,15 @@ FixAveForceCuda::FixAveForceCuda(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix aveforce command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix aveforce command"); iregion = domain->find_region(arg[iarg+1]); - if (iregion == -1) error->all("Fix aveforce region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Fix aveforce region ID does not exist"); iarg += 2; - } else error->all("Illegal fix aveforce command"); + } else error->all(FLERR,"Illegal fix aveforce command"); } - if(iregion!=-1) error->all("Error: fix aveforce/cuda does not currently support 'region' option"); + if(iregion!=-1) error->all(FLERR,"Error: fix aveforce/cuda does not currently support 'region' option"); foriginal_all[0] = foriginal_all[1] = foriginal_all[2] = foriginal_all[3] = 0.0; foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0; diff --git a/src/USER-CUDA/fix_enforce2d_cuda.cpp b/src/USER-CUDA/fix_enforce2d_cuda.cpp index 91a1661c08..d660814f2d 100644 --- a/src/USER-CUDA/fix_enforce2d_cuda.cpp +++ b/src/USER-CUDA/fix_enforce2d_cuda.cpp @@ -54,9 +54,9 @@ FixEnforce2DCuda::FixEnforce2DCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 3) error->all("Illegal fix enforce2d command"); + if (narg != 3) error->all(FLERR,"Illegal fix enforce2d command"); } /* ---------------------------------------------------------------------- */ @@ -75,15 +75,15 @@ int FixEnforce2DCuda::setmask() void FixEnforce2DCuda::init() { if (domain->dimension == 3) - error->all("Cannot use fix enforce2d/cuda with 3d simulation"); + error->all(FLERR,"Cannot use fix enforce2d/cuda with 3d simulation"); if (atom->omega_flag) - error->warning("Enforce2d/cuda does not support omega_flag on gpu yet. Will be handled on cpu."); + error->warning(FLERR,"Enforce2d/cuda does not support omega_flag on gpu yet. Will be handled on cpu."); if (atom->angmom_flag) - error->warning("Enforce2d/cuda does not support angmom_flag (angular momentum) on gpu yet. Will be handled on cpu."); + error->warning(FLERR,"Enforce2d/cuda does not support angmom_flag (angular momentum) on gpu yet. Will be handled on cpu."); if (atom->torque_flag) - error->warning("Enforce2d/cuda does not support torque_flag on gpu yet. Will be handled on cpu."); + error->warning(FLERR,"Enforce2d/cuda does not support torque_flag on gpu yet. Will be handled on cpu."); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-CUDA/fix_freeze_cuda.cpp b/src/USER-CUDA/fix_freeze_cuda.cpp index d52642280e..9e8f81c5f5 100644 --- a/src/USER-CUDA/fix_freeze_cuda.cpp +++ b/src/USER-CUDA/fix_freeze_cuda.cpp @@ -43,12 +43,12 @@ FixFreezeCuda::FixFreezeCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 3) error->all("Illegal fix freeze command"); + if (narg != 3) error->all(FLERR,"Illegal fix freeze command"); if (!atom->torque_flag) - error->all("Fix freeze requires atom attribute torque"); + error->all(FLERR,"Fix freeze requires atom attribute torque"); vector_flag = 1; size_vector = 3; @@ -81,7 +81,7 @@ void FixFreezeCuda::init() int count = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"freeze") == 0) count++; - if (count > 1) error->all("More than one fix freeze"); + if (count > 1) error->all(FLERR,"More than one fix freeze"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-CUDA/fix_gravity_cuda.cpp b/src/USER-CUDA/fix_gravity_cuda.cpp index 0c69dffcc1..8c6d8488c8 100644 --- a/src/USER-CUDA/fix_gravity_cuda.cpp +++ b/src/USER-CUDA/fix_gravity_cuda.cpp @@ -46,38 +46,38 @@ FixGravityCuda::FixGravityCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg < 5) error->all("Illegal fix gravity command"); + if (narg < 5) error->all(FLERR,"Illegal fix gravity command"); time_depend = 1; magnitude = atof(arg[3]); if (strcmp(arg[4],"chute") == 0) { - if (narg != 6) error->all("Illegal fix gravity command"); + if (narg != 6) error->all(FLERR,"Illegal fix gravity command"); style = CHUTE; phi = 0.0; theta = 180.0 - atof(arg[5]); } else if (strcmp(arg[4],"spherical") == 0) { - if (narg != 7) error->all("Illegal fix gravity command"); + if (narg != 7) error->all(FLERR,"Illegal fix gravity command"); style = SPHERICAL; phi = atof(arg[5]); theta = atof(arg[6]); } else if (strcmp(arg[4],"gradient") == 0) { - if (narg != 9) error->all("Illegal fix gravity command"); + if (narg != 9) error->all(FLERR,"Illegal fix gravity command"); style = GRADIENT; phi = atof(arg[5]); theta = atof(arg[6]); phigrad = atof(arg[7]); thetagrad = atof(arg[8]); } else if (strcmp(arg[4],"vector") == 0) { - if (narg != 8) error->all("Illegal fix gravity command"); + if (narg != 8) error->all(FLERR,"Illegal fix gravity command"); style = VECTOR; xdir = atof(arg[5]); ydir = atof(arg[6]); zdir = atof(arg[7]); - } else error->all("Illegal fix gravity command"); + } else error->all(FLERR,"Illegal fix gravity command"); double PI = 4.0*atan(1.0); degree2rad = PI/180.0; diff --git a/src/USER-CUDA/fix_nh_cuda.cpp b/src/USER-CUDA/fix_nh_cuda.cpp index 281ffaf0f6..cfbd3f7888 100644 --- a/src/USER-CUDA/fix_nh_cuda.cpp +++ b/src/USER-CUDA/fix_nh_cuda.cpp @@ -38,9 +38,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{NOBIAS,BIAS}; enum{NONE,XYZ,XY,YZ,XZ}; enum{ISO,ANISO,TRICLINIC}; @@ -53,9 +50,9 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg < 4) error->all("Illegal fix nvt/npt/nph command"); + if (narg < 4) error->all(FLERR,"Illegal fix nvt/npt/nph command"); restart_global = 1; time_integrate = 1; @@ -98,17 +95,17 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) while (iarg < narg) { if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); tstat_flag = 1; t_start = atof(arg[iarg+1]); t_stop = atof(arg[iarg+2]); t_period = atof(arg[iarg+3]); if (t_start < 0.0 || t_stop <= 0.0) - error->all("Target T for fix nvt/npt/nph cannot be 0.0"); + error->all(FLERR,"Target T for fix nvt/npt/nph cannot be 0.0"); iarg += 4; } else if (strcmp(arg[iarg],"iso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = XYZ; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -120,7 +117,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } iarg += 4; } else if (strcmp(arg[iarg],"aniso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = NONE; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -132,7 +129,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } iarg += 4; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = NONE; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -153,7 +150,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) iarg += 4; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[0] = atof(arg[iarg+1]); p_stop[0] = atof(arg[iarg+2]); p_period[0] = atof(arg[iarg+3]); @@ -161,7 +158,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[1] = atof(arg[iarg+1]); p_stop[1] = atof(arg[iarg+2]); p_period[1] = atof(arg[iarg+3]); @@ -169,7 +166,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[2] = atof(arg[iarg+1]); p_stop[2] = atof(arg[iarg+2]); p_period[2] = atof(arg[iarg+3]); @@ -177,10 +174,10 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"yz") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[3] = atof(arg[iarg+1]); p_stop[3] = atof(arg[iarg+2]); p_period[3] = atof(arg[iarg+3]); @@ -188,9 +185,9 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"xz") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[4] = atof(arg[iarg+1]); p_stop[4] = atof(arg[iarg+2]); p_period[4] = atof(arg[iarg+3]); @@ -198,9 +195,9 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"xy") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[5] = atof(arg[iarg+1]); p_stop[5] = atof(arg[iarg+2]); p_period[5] = atof(arg[iarg+3]); @@ -209,116 +206,116 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) iarg += 4; } else if (strcmp(arg[iarg],"couple") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ; else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY; else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ; else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ; else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"drag") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); drag = atof(arg[iarg+1]); - if (drag < 0.0) error->all("Illegal fix nvt/npt/nph command"); + if (drag < 0.0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"dilate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"all") == 0) allremap = 1; else if (strcmp(arg[iarg+1],"partial") == 0) allremap = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"tchain") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); mtchain = atoi(arg[iarg+1]); - if (mtchain < 1) error->all("Illegal fix nvt/npt/nph command"); + if (mtchain < 1) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"pchain") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); mpchain = atoi(arg[iarg+1]); - if (mpchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (mpchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"mtk") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"yes") == 0) mtk_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) mtk_flag = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"tloop") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nc_tchain = atoi(arg[iarg+1]); - if (nc_tchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nc_tchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"ploop") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nc_pchain = atoi(arg[iarg+1]); - if (nc_pchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nc_pchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"nreset") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nreset_h0 = atoi(arg[iarg+1]); - if (nreset_h0 < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nreset_h0 < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; - } else error->all("Illegal fix nvt/npt/nph command"); + } else error->all(FLERR,"Illegal fix nvt/npt/nph command"); } // error checks if (dimension == 2 && (p_flag[2] || p_flag[3] || p_flag[4])) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); if (dimension == 2 && (pcouple == YZ || pcouple == XZ)) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XYZ && dimension == 3 && p_flag[2] == 0) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (p_flag[0] && domain->xperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[1] && domain->yperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[2] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[3] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (p_flag[4] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (p_flag[5] && domain->yperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5])) - error->all("Can not specify Pxy/Pxz/Pyz in " + error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in " "fix nvt/npt/nph with non-triclinic box"); if (pcouple == XYZ && dimension == 3 && (p_start[0] != p_start[1] || p_start[0] != p_start[2] || p_stop[0] != p_stop[1] || p_stop[0] != p_stop[2] || p_period[0] != p_period[1] || p_period[0] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XYZ && dimension == 2 && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XY && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == YZ && (p_start[1] != p_start[2] || p_stop[1] != p_stop[2] || p_period[1] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XZ && (p_start[0] != p_start[2] || p_stop[0] != p_stop[2] || p_period[0] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if ((tstat_flag && t_period <= 0.0) || (p_flag[0] && p_period[0] <= 0.0) || @@ -327,7 +324,7 @@ FixNHCuda::FixNHCuda(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) (p_flag[3] && p_period[3] <= 0.0) || (p_flag[4] && p_period[4] <= 0.0) || (p_flag[5] && p_period[5] <= 0.0)) - error->all("Fix nvt/npt/nph damping parameters must be > 0.0"); + error->all(FLERR,"Fix nvt/npt/nph damping parameters must be > 0.0"); // set pstat_flag and box change variables @@ -480,7 +477,7 @@ void FixNHCuda::init() if ((p_flag[0] && dimflag[0]) || (p_flag[1] && dimflag[1]) || (p_flag[2] && dimflag[2]) || (p_flag[3] && dimflag[3]) || (p_flag[4] && dimflag[4]) || (p_flag[5] && dimflag[5])) - error->all("Cannot use fix npt and fix deform on " + error->all(FLERR,"Cannot use fix npt and fix deform on " "same component of stress tensor"); } @@ -488,7 +485,7 @@ void FixNHCuda::init() int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix nvt/nph/npt does not exist"); + error->all(FLERR,"Temperature ID for fix nvt/nph/npt does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -496,7 +493,7 @@ void FixNHCuda::init() if (pstat_flag) { icompute = modify->find_compute(id_press); - if (icompute < 0) error->all("Pressure ID for fix npt/nph does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for fix npt/nph does not exist"); pressure = modify->compute[icompute]; } @@ -1098,7 +1095,7 @@ void FixNHCuda::remap() if (domain->yz < -0.5*domain->yprd || domain->yz > 0.5*domain->yprd || domain->xz < -0.5*domain->xprd || domain->xz > 0.5*domain->xprd || domain->xy < -0.5*domain->xprd || domain->xy > 0.5*domain->xprd) - error->all("Fix npt/nph has tilted box too far - " + error->all(FLERR,"Fix npt/nph has tilted box too far - " "box flips are not yet implemented"); } @@ -1247,7 +1244,7 @@ void FixNHCuda::restart(char *buf) int FixNHCuda::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -1258,28 +1255,28 @@ int FixNHCuda::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for fix modify is not for group all"); + error->warning(FLERR,"Temperature for fix modify is not for group all"); // reset id_temp of pressure to new temperature ID if (pstat_flag) { icompute = modify->find_compute(id_press); if (icompute < 0) - error->all("Pressure ID for fix modify does not exist"); + error->all(FLERR,"Pressure ID for fix modify does not exist"); modify->compute[icompute]->reset_extra_compute_fix(id_temp); } return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); - if (!pstat_flag) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + if (!pstat_flag) error->all(FLERR,"Illegal fix_modify command"); if (pflag) { modify->delete_compute(id_press); pflag = 0; @@ -1290,11 +1287,11 @@ int FixNHCuda::modify_param(int narg, char **arg) strcpy(id_press,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); return 2; } diff --git a/src/USER-CUDA/fix_npt_cuda.cpp b/src/USER-CUDA/fix_npt_cuda.cpp index 3ad0d74efb..dbd395cbcf 100644 --- a/src/USER-CUDA/fix_npt_cuda.cpp +++ b/src/USER-CUDA/fix_npt_cuda.cpp @@ -25,12 +25,12 @@ FixNPTCuda::FixNPTCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); if (!tstat_flag) - error->all("Temperature control must be used with fix npt"); + error->all(FLERR,"Temperature control must be used with fix npt"); if (!pstat_flag) - error->all("Pressure control must be used with fix npt"); + error->all(FLERR,"Pressure control must be used with fix npt"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/USER-CUDA/fix_nve_cuda.cpp b/src/USER-CUDA/fix_nve_cuda.cpp index 88ef34dbfe..f498169c3e 100644 --- a/src/USER-CUDA/fix_nve_cuda.cpp +++ b/src/USER-CUDA/fix_nve_cuda.cpp @@ -56,10 +56,10 @@ FixNVECuda::FixNVECuda(LAMMPS *lmp, int narg, char **arg) : cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); if (strcmp(style,"nve/sphere") != 0 && narg < 3) - error->all("Illegal fix nve command"); + error->all(FLERR,"Illegal fix nve command"); time_integrate = 1; } diff --git a/src/USER-CUDA/fix_nvt_cuda.cpp b/src/USER-CUDA/fix_nvt_cuda.cpp index 49a3c63013..3d66a67e4b 100644 --- a/src/USER-CUDA/fix_nvt_cuda.cpp +++ b/src/USER-CUDA/fix_nvt_cuda.cpp @@ -25,9 +25,9 @@ FixNVTCuda::FixNVTCuda(LAMMPS *lmp, int narg, char **arg) : FixNHCuda(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt"); + error->all(FLERR,"Temperature control must be used with fix nvt"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt"); + error->all(FLERR,"Pressure control can not be used with fix nvt"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/USER-CUDA/fix_set_force_cuda.cpp b/src/USER-CUDA/fix_set_force_cuda.cpp index bd9665c8cc..e54f64d22d 100644 --- a/src/USER-CUDA/fix_set_force_cuda.cpp +++ b/src/USER-CUDA/fix_set_force_cuda.cpp @@ -42,9 +42,9 @@ FixSetForceCuda::FixSetForceCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 6) error->all("Illegal fix setforce/cuda command"); + if (narg != 6) error->all(FLERR,"Illegal fix setforce/cuda command"); vector_flag = 1; size_vector = 3; diff --git a/src/USER-CUDA/fix_shake_cuda.cpp b/src/USER-CUDA/fix_shake_cuda.cpp index 20883889cf..219ac679bd 100644 --- a/src/USER-CUDA/fix_shake_cuda.cpp +++ b/src/USER-CUDA/fix_shake_cuda.cpp @@ -39,8 +39,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 #define MASSDELTA 0.1 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) /* ---------------------------------------------------------------------- */ @@ -49,7 +47,7 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); cuda->accelerator(0,NULL); MPI_Comm_rank(world,&me); @@ -63,7 +61,7 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : // error check if (atom->molecular == 0) - error->all("Cannot use fix shake with non-molecular system"); + error->all(FLERR,"Cannot use fix shake with non-molecular system"); // perform initial allocation of atom-based arrays // register with Atom class @@ -88,7 +86,7 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : // parse SHAKE args - if (narg < 8) error->all("Illegal fix shake command"); + if (narg < 8) error->all(FLERR,"Illegal fix shake command"); tolerance = atof(arg[3]); max_iter = atoi(arg[4]); @@ -123,28 +121,28 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : } else if (mode == 'b') { int i = atoi(arg[next]); if (i < 1 || i > atom->nbondtypes) - error->all("Invalid bond type index for fix shake"); + error->all(FLERR,"Invalid bond type index for fix shake"); bond_flag[i] = 1; } else if (mode == 'a') { int i = atoi(arg[next]); if (i < 1 || i > atom->nangletypes) - error->all("Invalid angle type index for fix shake"); + error->all(FLERR,"Invalid angle type index for fix shake"); angle_flag[i] = 1; } else if (mode == 't') { int i = atoi(arg[next]); if (i < 1 || i > atom->ntypes) - error->all("Invalid atom type index for fix shake"); + error->all(FLERR,"Invalid atom type index for fix shake"); type_flag[i] = 1; } else if (mode == 'm') { double massone = atof(arg[next]); - if (massone == 0.0) error->all("Invalid atom mass for fix shake"); - if (nmass == atom->ntypes) error->all("Too many masses for fix shake"); + if (massone == 0.0) error->all(FLERR,"Invalid atom mass for fix shake"); + if (nmass == atom->ntypes) error->all(FLERR,"Too many masses for fix shake"); mass_list[nmass++] = massone; - } else error->all("Illegal fix shake command"); + } else error->all(FLERR,"Illegal fix shake command"); next++; } @@ -312,13 +310,13 @@ void FixShakeCuda::init() int count = 0; for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"shake") == 0) count++; - if (count > 1) error->all("More than one fix shake"); + if (count > 1) error->all(FLERR,"More than one fix shake"); // cannot use with minimization since SHAKE turns off bonds // that should contribute to potential energy if (update->whichflag == 2) - error->all("Fix shake cannot be used with minimization"); + error->all(FLERR,"Fix shake cannot be used with minimization"); // error if npt,nph fix comes before shake fix @@ -329,7 +327,7 @@ void FixShakeCuda::init() if (i < modify->nfix) { for (int j = i; j < modify->nfix; j++) if (strcmp(modify->fix[j]->style,"shake") == 0) - error->all("Shake fix must come before NPT/NPH fix"); + error->all(FLERR,"Shake fix must come before NPT/NPH fix"); } // if rRESPA, find associated fix that must exist @@ -347,7 +345,7 @@ void FixShakeCuda::init() // set equilibrium bond distances if (force->bond == NULL) - error->all("Bond potential must be defined for SHAKE"); + error->all(FLERR,"Bond potential must be defined for SHAKE"); for (i = 1; i <= atom->nbondtypes; i++) bond_distance[i] = force->bond->equilibrium_distance(i); @@ -358,7 +356,7 @@ void FixShakeCuda::init() for (i = 1; i <= atom->nangletypes; i++) { if (angle_flag[i] == 0) continue; if (force->angle == NULL) - error->all("Angle potential must be defined for SHAKE"); + error->all(FLERR,"Angle potential must be defined for SHAKE"); // scan all atoms for a SHAKE angle cluster // extract bond types for the 2 bonds in the cluster @@ -385,7 +383,7 @@ void FixShakeCuda::init() // error check for any bond types that are not the same MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world); - if (flag_all) error->all("Shake angles have different bond types"); + if (flag_all) error->all(FLERR,"Shake angles have different bond types"); // insure all procs have bond types @@ -500,7 +498,7 @@ void FixShakeCuda::pre_neighbor() sprintf(str, "Shake atoms %d %d missing on proc %d at step " BIGINT_FORMAT, shake_atom[i][0],shake_atom[i][1],me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2) list[nlist++] = i; } else if (shake_flag[i] % 2 == 1) { @@ -514,7 +512,7 @@ void FixShakeCuda::pre_neighbor() BIGINT_FORMAT, shake_atom[i][0],shake_atom[i][1],shake_atom[i][2], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2 && i <= atom3) list[nlist++] = i; } else { @@ -530,7 +528,7 @@ void FixShakeCuda::pre_neighbor() shake_atom[i][0],shake_atom[i][1], shake_atom[i][2],shake_atom[i][3], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4) list[nlist++] = i; @@ -906,7 +904,7 @@ void FixShakeCuda::find_clusters() } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Did not find fix shake partner info"); + if (flag_all) error->all(FLERR,"Did not find fix shake partner info"); // ----------------------------------------------------- // identify SHAKEable bonds @@ -1040,7 +1038,7 @@ void FixShakeCuda::find_clusters() flag = 0; for (i = 0; i < nlocal; i++) if (nshake[i] > 3) flag = 1; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Shake cluster of more than 4 atoms"); + if (flag_all) error->all(FLERR,"Shake cluster of more than 4 atoms"); flag = 0; for (i = 0; i < nlocal; i++) { @@ -1049,7 +1047,7 @@ void FixShakeCuda::find_clusters() if (partner_shake[i][j] && partner_nshake[i][j] > 1) flag = 1; } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Shake clusters are connected"); + if (flag_all) error->all(FLERR,"Shake clusters are connected"); // ----------------------------------------------------- // set SHAKE arrays that are stored with atoms & add angle constraints @@ -1418,7 +1416,7 @@ void FixShakeCuda::shake2(int m) double determ = b*b - 4.0*a*c; if (determ < 0.0) { - error->warning("Shake determinant < 0.0"); + error->warning(FLERR,"Shake determinant < 0.0"); determ = 0.0; } @@ -1537,7 +1535,7 @@ void FixShakeCuda::shake3(int m) // inverse of matrix double determ = a11*a22 - a12*a21; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = a22*determinv; @@ -1731,7 +1729,7 @@ void FixShakeCuda::shake4(int m) double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = determinv * (a22*a33 - a23*a32); @@ -1972,7 +1970,7 @@ void FixShakeCuda::shake3angle(int m) double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = determinv * (a22*a33 - a23*a32); diff --git a/src/USER-CUDA/fix_temp_berendsen_cuda.cpp b/src/USER-CUDA/fix_temp_berendsen_cuda.cpp index 5fe9b0544a..697ddbefd1 100644 --- a/src/USER-CUDA/fix_temp_berendsen_cuda.cpp +++ b/src/USER-CUDA/fix_temp_berendsen_cuda.cpp @@ -61,9 +61,9 @@ FixTempBerendsenCuda::FixTempBerendsenCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg != 6) error->all("Illegal fix temp/berendsen/cuda command"); + if (narg != 6) error->all(FLERR,"Illegal fix temp/berendsen/cuda command"); // Berendsen thermostat should be applied every step @@ -75,7 +75,7 @@ FixTempBerendsenCuda::FixTempBerendsenCuda(LAMMPS *lmp, int narg, char **arg) : // error checks - if (t_period <= 0.0) error->all("Fix temp/berendsen/cuda period must be > 0.0"); + if (t_period <= 0.0) error->all(FLERR,"Fix temp/berendsen/cuda period must be > 0.0"); // create a new compute temp style // id = fix-ID + temp, compute group = fix group @@ -119,10 +119,10 @@ void FixTempBerendsenCuda::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/berendsen/cuda does not exist"); + error->all(FLERR,"Temperature ID for fix temp/berendsen/cuda does not exist"); temperature = modify->compute[icompute]; if(not temperature->cudable) - error->warning("Fix temp/berendsen/cuda uses non cudable temperature compute"); + error->warning(FLERR,"Fix temp/berendsen/cuda uses non cudable temperature compute"); if (temperature->tempbias) which = BIAS; else which = NOBIAS; @@ -137,7 +137,7 @@ void FixTempBerendsenCuda::end_of_step() if(not temperature->cudable) {cuda->cu_x->download();cuda->cu_v->download();} t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/berendsen/cuda cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/berendsen/cuda cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -185,7 +185,7 @@ void FixTempBerendsenCuda::end_of_step() int FixTempBerendsenCuda::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -196,13 +196,13 @@ int FixTempBerendsenCuda::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/USER-CUDA/fix_temp_rescale_cuda.cpp b/src/USER-CUDA/fix_temp_rescale_cuda.cpp index a633bdc861..df23ef36a4 100644 --- a/src/USER-CUDA/fix_temp_rescale_cuda.cpp +++ b/src/USER-CUDA/fix_temp_rescale_cuda.cpp @@ -50,12 +50,12 @@ FixTempRescaleCuda::FixTempRescaleCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg < 8) error->all("Illegal fix temp/rescale/cuda command"); + if (narg < 8) error->all(FLERR,"Illegal fix temp/rescale/cuda command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix temp/rescale/cuda command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix temp/rescale/cuda command"); scalar_flag = 1; global_freq = nevery; @@ -111,10 +111,10 @@ void FixTempRescaleCuda::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/rescale/cuda does not exist"); + error->all(FLERR,"Temperature ID for fix temp/rescale/cuda does not exist"); temperature = modify->compute[icompute]; if(not temperature->cudable) - error->warning("Fix temp/rescale/cuda uses non cudable temperature compute"); + error->warning(FLERR,"Fix temp/rescale/cuda uses non cudable temperature compute"); if (temperature->tempbias) which = BIAS; else which = NOBIAS; } @@ -127,7 +127,7 @@ void FixTempRescaleCuda::end_of_step() if(not temperature->cudable) {cuda->cu_x->download();cuda->cu_v->download();} t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/rescale/cuda cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/rescale/cuda cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -181,7 +181,7 @@ void FixTempRescaleCuda::end_of_step() int FixTempRescaleCuda::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -192,15 +192,15 @@ int FixTempRescaleCuda::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); if(not temperature->cudable) - error->warning("Fix temp/rescale/cuda uses non cudable temperature compute"); + error->warning(FLERR,"Fix temp/rescale/cuda uses non cudable temperature compute"); return 2; } return 0; diff --git a/src/USER-CUDA/fix_temp_rescale_limit_cuda.cpp b/src/USER-CUDA/fix_temp_rescale_limit_cuda.cpp index be2d6a1f29..875cb391a5 100644 --- a/src/USER-CUDA/fix_temp_rescale_limit_cuda.cpp +++ b/src/USER-CUDA/fix_temp_rescale_limit_cuda.cpp @@ -40,8 +40,6 @@ #include "cuda_modify_flags.h" using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) enum{NOBIAS,BIAS}; @@ -52,12 +50,12 @@ FixTempRescaleLimitCuda::FixTempRescaleLimitCuda(LAMMPS *lmp, int narg, char **a { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if (narg < 9) error->all("Illegal fix temp/rescale/limit/cuda command"); + if (narg < 9) error->all(FLERR,"Illegal fix temp/rescale/limit/cuda command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix temp/rescale/limit/cuda command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix temp/rescale/limit/cuda command"); scalar_flag = 1; global_freq = nevery; @@ -68,7 +66,7 @@ FixTempRescaleLimitCuda::FixTempRescaleLimitCuda(LAMMPS *lmp, int narg, char **a t_window = atof(arg[6]); fraction = atof(arg[7]); limit = atof(arg[8]); - if (limit <= 1.0) error->all("Illegal fix temp/rescale/limit/cuda command (limit must be > 1.0)"); + if (limit <= 1.0) error->all(FLERR,"Illegal fix temp/rescale/limit/cuda command (limit must be > 1.0)"); // create a new compute temp @@ -116,10 +114,10 @@ void FixTempRescaleLimitCuda::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/rescale/limit/cuda does not exist"); + error->all(FLERR,"Temperature ID for fix temp/rescale/limit/cuda does not exist"); temperature = modify->compute[icompute]; if(not temperature->cudable) - error->warning("Fix temp/rescale/limit/cuda uses non cudable temperature compute"); + error->warning(FLERR,"Fix temp/rescale/limit/cuda uses non cudable temperature compute"); if (temperature->tempbias) which = BIAS; else which = NOBIAS; } @@ -132,7 +130,7 @@ void FixTempRescaleLimitCuda::end_of_step() if(not temperature->cudable) {cuda->cu_x->download();cuda->cu_v->download();} t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/rescale/limit/cuda cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/rescale/limit/cuda cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -196,7 +194,7 @@ void FixTempRescaleLimitCuda::end_of_step() int FixTempRescaleLimitCuda::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -207,15 +205,15 @@ int FixTempRescaleLimitCuda::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); if(not temperature->cudable) - error->warning("Fix temp/rescale/limit/cuda uses non cudable temperature compute"); + error->warning(FLERR,"Fix temp/rescale/limit/cuda uses non cudable temperature compute"); return 2; } return 0; diff --git a/src/USER-CUDA/fix_viscous_cuda.cpp b/src/USER-CUDA/fix_viscous_cuda.cpp index 37509dcb35..e0f32e7b69 100644 --- a/src/USER-CUDA/fix_viscous_cuda.cpp +++ b/src/USER-CUDA/fix_viscous_cuda.cpp @@ -42,7 +42,7 @@ FixViscousCuda::FixViscousCuda(LAMMPS *lmp, int narg, char **arg) : { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); cu_gamma=NULL; } diff --git a/src/USER-CUDA/modify_cuda.cpp b/src/USER-CUDA/modify_cuda.cpp index 6eb832803d..9fd0435892 100644 --- a/src/USER-CUDA/modify_cuda.cpp +++ b/src/USER-CUDA/modify_cuda.cpp @@ -53,9 +53,6 @@ using namespace LAMMPS_NS; #include "cuda_modify_flags.h" -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ @@ -64,7 +61,7 @@ ModifyCuda::ModifyCuda(LAMMPS *lmp) : Modify(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); n_initial_integrate_cuda = 0; n_post_integrate_cuda = 0; @@ -242,7 +239,7 @@ void ModifyCuda::init() int checkall; MPI_Allreduce(&check,&checkall,1,MPI_INT,MPI_SUM,world); if (comm->me == 0 && checkall) - error->warning("One or more atoms are time integrated more than once"); + error->warning(FLERR,"One or more atoms are time integrated more than once"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-CUDA/neigh_full_cuda.cpp b/src/USER-CUDA/neigh_full_cuda.cpp index 197b62a0ac..61c9897f4a 100644 --- a/src/USER-CUDA/neigh_full_cuda.cpp +++ b/src/USER-CUDA/neigh_full_cuda.cpp @@ -40,7 +40,7 @@ using namespace LAMMPS_NS; void NeighborCuda::full_bin_cuda(NeighList *list) { MYDBG(printf(" # CUDA::NeighFullBinCuda ... start\n");) - if(includegroup) error->warning("Warning using inlcudegroup neighborbuild. This is not yet supported by CUDA neighborbuild styles.\n"); + if(includegroup) error->warning(FLERR,"Warning using inlcudegroup neighborbuild. This is not yet supported by CUDA neighborbuild styles.\n"); int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; @@ -93,7 +93,7 @@ void NeighborCuda::full_bin_cuda(NeighList *list) slist->binned_id=(int*) CudaWrapper_AllocCudaData(slist->bin_dim[0]*slist->bin_dim[1]*slist->bin_dim[2]*slist->bin_nmax*sizeof(int)); //printf("slist->bin: %i %i %i %i \n", bin_dim_tmp[0],bin_dim_tmp[1],bin_dim_tmp[2],bin_nmax_tmp); } - //if(list->cuda_list->sneighlist.bin_nmax>512) error->all("To many atoms per bin. Likely cause is very long pair cutoff. This needs major rewrite of code and is not yet scheduled to be done.\n"); + //if(list->cuda_list->sneighlist.bin_nmax>512) error->all(FLERR,"To many atoms per bin. Likely cause is very long pair cutoff. This needs major rewrite of code and is not yet scheduled to be done.\n"); }while(Cuda_BinAtoms(&cuda->shared_data, &list->cuda_list->sneighlist)); // cuda->cu_debugdata->memset_device(0); diff --git a/src/USER-CUDA/neighbor_cuda.cpp b/src/USER-CUDA/neighbor_cuda.cpp index e8f317afd3..99bf2dce3c 100644 --- a/src/USER-CUDA/neighbor_cuda.cpp +++ b/src/USER-CUDA/neighbor_cuda.cpp @@ -26,9 +26,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ @@ -37,7 +34,7 @@ NeighborCuda::NeighborCuda(LAMMPS *lmp) : Neighbor(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); } /* ---------------------------------------------------------------------- */ @@ -206,7 +203,7 @@ void NeighborCuda::build() // check that neighbor list with special bond flags will not overflow if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one("Too many local+ghost atoms for neighbor list"); + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); // invoke building of pair and molecular neighbor lists // only for pairwise lists with buildflag set diff --git a/src/USER-CUDA/pair_born_coul_long_cuda.cpp b/src/USER-CUDA/pair_born_coul_long_cuda.cpp index 1d8c656316..f5aaff51f0 100644 --- a/src/USER-CUDA/pair_born_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_born_coul_long_cuda.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -62,7 +59,7 @@ PairBornCoulLongCuda::PairBornCoulLongCuda(LAMMPS *lmp) : PairBornCoulLong(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -134,12 +131,12 @@ void PairBornCoulLongCuda::coeff(int narg, char **arg) void PairBornCoulLongCuda::init_style() { if (!atom->q_flag) - error->all("Pair style born/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style born/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; - if (strstr(update->integrate_style,"respa")) error->all("Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); + if (strstr(update->integrate_style,"respa")) error->all(FLERR,"Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); irequest = neighbor->request(this); neighbor->requests[irequest]->full = 1; @@ -151,13 +148,13 @@ void PairBornCoulLongCuda::init_style() cuda->shared_data.pair.cut_coulsq_global=cut_coulsq; if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairBornCoulLongCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_buck_coul_cut_cuda.cpp b/src/USER-CUDA/pair_buck_coul_cut_cuda.cpp index 4416a3d197..bc08546184 100644 --- a/src/USER-CUDA/pair_buck_coul_cut_cuda.cpp +++ b/src/USER-CUDA/pair_buck_coul_cut_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairBuckCoulCutCuda::PairBuckCoulCutCuda(LAMMPS *lmp) : PairBuckCoulCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -127,12 +124,12 @@ void PairBuckCoulCutCuda::coeff(int narg, char **arg) void PairBuckCoulCutCuda::init_style() { if (!atom->q_flag) - error->all("Pair style buck/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style buck/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; - if (strstr(update->integrate_style,"respa")) error->all("Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); + if (strstr(update->integrate_style,"respa")) error->all(FLERR,"Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); irequest = neighbor->request(this); neighbor->requests[irequest]->full = 1; @@ -144,7 +141,7 @@ void PairBuckCoulCutCuda::init_style() cuda->shared_data.pair.cut_coulsq_global=cut_coul_global * cut_coul_global; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairBuckCoulCutCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_buck_coul_long_cuda.cpp b/src/USER-CUDA/pair_buck_coul_long_cuda.cpp index 9044d2128c..4cbd304e07 100644 --- a/src/USER-CUDA/pair_buck_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_buck_coul_long_cuda.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -62,7 +59,7 @@ PairBuckCoulLongCuda::PairBuckCoulLongCuda(LAMMPS *lmp) : PairBuckCoulLong(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -132,12 +129,12 @@ void PairBuckCoulLongCuda::coeff(int narg, char **arg) void PairBuckCoulLongCuda::init_style() { if (!atom->q_flag) - error->all("Pair style buck/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style buck/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; - if (strstr(update->integrate_style,"respa")) error->all("Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); + if (strstr(update->integrate_style,"respa")) error->all(FLERR,"Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); irequest = neighbor->request(this); neighbor->requests[irequest]->full = 1; @@ -149,13 +146,13 @@ void PairBuckCoulLongCuda::init_style() cuda->shared_data.pair.cut_coulsq_global=cut_coulsq; if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairBuckCoulLongCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_buck_cuda.cpp b/src/USER-CUDA/pair_buck_cuda.cpp index e906783390..a537e600ed 100644 --- a/src/USER-CUDA/pair_buck_cuda.cpp +++ b/src/USER-CUDA/pair_buck_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairBuckCuda::PairBuckCuda(LAMMPS *lmp) : PairBuck(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -124,12 +121,12 @@ void PairBuckCuda::coeff(int narg, char **arg) void PairBuckCuda::init_style() { if (!atom->q_flag) - error->all("Pair style buck/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style buck/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; - if (strstr(update->integrate_style,"respa")) error->all("Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); + if (strstr(update->integrate_style,"respa")) error->all(FLERR,"Integrate Style Respa is not supported by pair style buck/coul/long/cuda"); irequest = neighbor->request(this); neighbor->requests[irequest]->full = 1; @@ -140,7 +137,7 @@ void PairBuckCuda::init_style() cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairBuckCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_cg_cmm_coul_cut_cuda.cpp b/src/USER-CUDA/pair_cg_cmm_coul_cut_cuda.cpp index 1c82a8d797..5334e91f97 100644 --- a/src/USER-CUDA/pair_cg_cmm_coul_cut_cuda.cpp +++ b/src/USER-CUDA/pair_cg_cmm_coul_cut_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairCGCMMCoulCutCuda::PairCGCMMCoulCutCuda(LAMMPS *lmp) : PairCGCMMCoulCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cg_type_double = NULL; @@ -171,7 +168,7 @@ void PairCGCMMCoulCutCuda::init_style() cuda->shared_data.pppm.qqrd2e=force->qqrd2e; cut_respa=NULL; - if (force->newton) error->warning("Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); + if (force->newton) error->warning(FLERR,"Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); MYDBG(printf("# CUDA PairCGCMMCoulCutCuda::init_style end\n"); ) } diff --git a/src/USER-CUDA/pair_cg_cmm_coul_debye_cuda.cpp b/src/USER-CUDA/pair_cg_cmm_coul_debye_cuda.cpp index 280ec2638a..862d8e56b3 100644 --- a/src/USER-CUDA/pair_cg_cmm_coul_debye_cuda.cpp +++ b/src/USER-CUDA/pair_cg_cmm_coul_debye_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairCGCMMCoulDebyeCuda::PairCGCMMCoulDebyeCuda(LAMMPS *lmp) : PairCGCMMCoulCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cg_type_double = NULL; @@ -171,7 +168,7 @@ void PairCGCMMCoulDebyeCuda::init_style() cuda->shared_data.pppm.qqrd2e=force->qqrd2e; cut_respa=NULL; - if (force->newton) error->warning("Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); + if (force->newton) error->warning(FLERR,"Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); MYDBG(printf("# CUDA PairCGCMMCoulDebyeCuda::init_style end\n"); ) } diff --git a/src/USER-CUDA/pair_cg_cmm_coul_long_cuda.cpp b/src/USER-CUDA/pair_cg_cmm_coul_long_cuda.cpp index 3597691690..c2d4ede4b4 100644 --- a/src/USER-CUDA/pair_cg_cmm_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_cg_cmm_coul_long_cuda.cpp @@ -62,16 +62,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairCGCMMCoulLongCuda::PairCGCMMCoulLongCuda(LAMMPS *lmp) : PairCGCMMCoulLong(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cg_type_double = NULL; @@ -174,7 +171,7 @@ void PairCGCMMCoulLongCuda::init_style() cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; cut_respa=NULL; - if (force->newton) error->warning("Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); + if (force->newton) error->warning(FLERR,"Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); MYDBG(printf("# CUDA PairCGCMMCoulLongCuda::init_style end\n"); ) } diff --git a/src/USER-CUDA/pair_cg_cmm_cuda.cpp b/src/USER-CUDA/pair_cg_cmm_cuda.cpp index 5471d95f23..cc3e5e585b 100644 --- a/src/USER-CUDA/pair_cg_cmm_cuda.cpp +++ b/src/USER-CUDA/pair_cg_cmm_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairCGCMMCuda::PairCGCMMCuda(LAMMPS *lmp) : PairCGCMM(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cg_type_double = NULL; diff --git a/src/USER-CUDA/pair_eam_alloy_cuda.cpp b/src/USER-CUDA/pair_eam_alloy_cuda.cpp index eb70fcc127..fd78c57133 100644 --- a/src/USER-CUDA/pair_eam_alloy_cuda.cpp +++ b/src/USER-CUDA/pair_eam_alloy_cuda.cpp @@ -34,7 +34,7 @@ PairEAMAlloyCuda::PairEAMAlloyCuda(LAMMPS *lmp) : PairEAMCuda(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); one_coeff = 1; } @@ -51,12 +51,12 @@ void PairEAMAlloyCuda::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read EAM setfl file @@ -83,7 +83,7 @@ void PairEAMAlloyCuda::coeff(int narg, char **arg) for (j = 0; j < setfl->nelements; j++) if (strcmp(arg[i],setfl->elements[j]) == 0) break; if (j < setfl->nelements) map[i-2] = j; - else error->all("No matching element in EAM potential file"); + else error->all(FLERR,"No matching element in EAM potential file"); } // clear setflag since coeff() called once with I,J = * * @@ -107,7 +107,7 @@ void PairEAMAlloyCuda::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -129,7 +129,7 @@ void PairEAMAlloyCuda::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -150,7 +150,7 @@ void PairEAMAlloyCuda::read_file(char *filename) sscanf(line,"%d",&file->nelements); int nwords = atom->count_words(line); if (nwords != file->nelements + 1) - error->all("Incorrect element names in EAM potential file"); + error->all(FLERR,"Incorrect element names in EAM potential file"); char **words = new char*[file->nelements+1]; nwords = 0; diff --git a/src/USER-CUDA/pair_eam_cuda.cpp b/src/USER-CUDA/pair_eam_cuda.cpp index 6d012a80a3..1c9c710a9f 100644 --- a/src/USER-CUDA/pair_eam_cuda.cpp +++ b/src/USER-CUDA/pair_eam_cuda.cpp @@ -62,16 +62,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairEAMCuda::PairEAMCuda(LAMMPS *lmp) : PairEAM(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_eam_fs_cuda.cpp b/src/USER-CUDA/pair_eam_fs_cuda.cpp index c7dd6e4ee3..13efb5a4fe 100644 --- a/src/USER-CUDA/pair_eam_fs_cuda.cpp +++ b/src/USER-CUDA/pair_eam_fs_cuda.cpp @@ -34,7 +34,7 @@ PairEAMFSCuda::PairEAMFSCuda(LAMMPS *lmp) : PairEAMCuda(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); one_coeff = 1; } @@ -51,12 +51,12 @@ void PairEAMFSCuda::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read EAM Finnis-Sinclair file @@ -83,7 +83,7 @@ void PairEAMFSCuda::coeff(int narg, char **arg) for (j = 0; j < fs->nelements; j++) if (strcmp(arg[i],fs->elements[j]) == 0) break; if (j < fs->nelements) map[i-2] = j; - else error->all("No matching element in EAM potential file"); + else error->all(FLERR,"No matching element in EAM potential file"); } // clear setflag since coeff() called once with I,J = * * @@ -107,7 +107,7 @@ void PairEAMFSCuda::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -129,7 +129,7 @@ void PairEAMFSCuda::read_file(char *filename) if (fptr == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s",filename); - error->one(str); + error->one(FLERR,str); } } @@ -150,7 +150,7 @@ void PairEAMFSCuda::read_file(char *filename) sscanf(line,"%d",&file->nelements); int nwords = atom->count_words(line); if (nwords != file->nelements + 1) - error->all("Incorrect element names in EAM potential file"); + error->all(FLERR,"Incorrect element names in EAM potential file"); char **words = new char*[file->nelements+1]; nwords = 0; diff --git a/src/USER-CUDA/pair_gran_hooke_cuda.cpp b/src/USER-CUDA/pair_gran_hooke_cuda.cpp index 6d3dd73248..74a3dbca8d 100644 --- a/src/USER-CUDA/pair_gran_hooke_cuda.cpp +++ b/src/USER-CUDA/pair_gran_hooke_cuda.cpp @@ -63,16 +63,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairGranHookeCuda::PairGranHookeCuda(LAMMPS *lmp) : PairGranHooke(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -163,9 +160,9 @@ void PairGranHookeCuda::init_style() } if (!atom->radius_flag || !atom->omega_flag || !atom->torque_flag) - error->all("Pair granular requires atom attributes radius, omega, torque"); + error->all(FLERR,"Pair granular requires atom attributes radius, omega, torque"); if (comm->ghost_velocity == 0) - error->all("Pair granular requires ghost atoms store velocity"); + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); // need a half neigh list and optionally a granular history neigh list diff --git a/src/USER-CUDA/pair_lj96_cut_cuda.cpp b/src/USER-CUDA/pair_lj96_cut_cuda.cpp index f60c61bf28..408665d85e 100644 --- a/src/USER-CUDA/pair_lj96_cut_cuda.cpp +++ b/src/USER-CUDA/pair_lj96_cut_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJ96CutCuda::PairLJ96CutCuda(LAMMPS *lmp) : PairLJ96Cut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_charmm_coul_charmm_cuda.cpp b/src/USER-CUDA/pair_lj_charmm_coul_charmm_cuda.cpp index a5a08046a9..bcd3569094 100644 --- a/src/USER-CUDA/pair_lj_charmm_coul_charmm_cuda.cpp +++ b/src/USER-CUDA/pair_lj_charmm_coul_charmm_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCharmmCoulCharmmCuda::PairLJCharmmCoulCharmmCuda(LAMMPS *lmp) : PairLJCharmmCoulCharmm(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -130,7 +127,7 @@ void PairLJCharmmCoulCharmmCuda::coeff(int narg, char **arg) void PairLJCharmmCoulCharmmCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists if(atom->molecular) @@ -146,7 +143,7 @@ void PairLJCharmmCoulCharmmCuda::init_style() neighbor->requests[irequest]->cudable = 1; if (cut_lj_inner >= cut_lj || cut_coul_inner >= cut_coul) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; diff --git a/src/USER-CUDA/pair_lj_charmm_coul_charmm_implicit_cuda.cpp b/src/USER-CUDA/pair_lj_charmm_coul_charmm_implicit_cuda.cpp index f127d9e31a..10696094c0 100644 --- a/src/USER-CUDA/pair_lj_charmm_coul_charmm_implicit_cuda.cpp +++ b/src/USER-CUDA/pair_lj_charmm_coul_charmm_implicit_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCharmmCoulCharmmImplicitCuda::PairLJCharmmCoulCharmmImplicitCuda(LAMMPS *lmp) : PairLJCharmmCoulCharmmImplicit(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -130,7 +127,7 @@ void PairLJCharmmCoulCharmmImplicitCuda::coeff(int narg, char **arg) void PairLJCharmmCoulCharmmImplicitCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; @@ -141,7 +138,7 @@ void PairLJCharmmCoulCharmmImplicitCuda::init_style() neighbor->requests[irequest]->cudable = 1; if (cut_lj_inner >= cut_lj || cut_coul_inner >= cut_coul) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; diff --git a/src/USER-CUDA/pair_lj_charmm_coul_long_cuda.cpp b/src/USER-CUDA/pair_lj_charmm_coul_long_cuda.cpp index 434f098f37..29629f1ed5 100644 --- a/src/USER-CUDA/pair_lj_charmm_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_lj_charmm_coul_long_cuda.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -62,7 +59,7 @@ PairLJCharmmCoulLongCuda::PairLJCharmmCoulLongCuda(LAMMPS *lmp) : PairLJCharmmCo { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -139,7 +136,7 @@ void PairLJCharmmCoulLongCuda::coeff(int narg, char **arg) void PairLJCharmmCoulLongCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/charmm/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/charmm/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; @@ -151,7 +148,7 @@ void PairLJCharmmCoulLongCuda::init_style() neighbor->requests[irequest]->cudable = 1; if (cut_lj_inner >= cut_lj) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; @@ -165,13 +162,13 @@ void PairLJCharmmCoulLongCuda::init_style() cuda->shared_data.pair.cut_coulsq_global=cut_coulsq; if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairLJCharmmCoulLongCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_lj_class2_coul_cut_cuda.cpp b/src/USER-CUDA/pair_lj_class2_coul_cut_cuda.cpp index a75a70ba01..702f2089c9 100644 --- a/src/USER-CUDA/pair_lj_class2_coul_cut_cuda.cpp +++ b/src/USER-CUDA/pair_lj_class2_coul_cut_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJClass2CoulCutCuda::PairLJClass2CoulCutCuda(LAMMPS *lmp) : PairLJClass2CoulCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -123,7 +120,7 @@ void PairLJClass2CoulCutCuda::coeff(int narg, char **arg) void PairLJClass2CoulCutCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut/cuda requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/cut/cuda requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; diff --git a/src/USER-CUDA/pair_lj_class2_coul_long_cuda.cpp b/src/USER-CUDA/pair_lj_class2_coul_long_cuda.cpp index 5c1d3a6fff..44f0fb3f2f 100644 --- a/src/USER-CUDA/pair_lj_class2_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_lj_class2_coul_long_cuda.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -62,7 +59,7 @@ PairLJClass2CoulLongCuda::PairLJClass2CoulLongCuda(LAMMPS *lmp) : PairLJClass2Co { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -128,7 +125,7 @@ void PairLJClass2CoulLongCuda::coeff(int narg, char **arg) void PairLJClass2CoulLongCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; @@ -144,15 +141,15 @@ void PairLJClass2CoulLongCuda::init_style() cuda->shared_data.pair.cut_coulsq_global=cut_coulsq; // set rRESPA cutoffs - if (force->newton) error->warning("Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); + if (force->newton) error->warning(FLERR,"Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairLJClass2CoulLongCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_lj_class2_cuda.cpp b/src/USER-CUDA/pair_lj_class2_cuda.cpp index 98d8d87468..a218dc9cc8 100644 --- a/src/USER-CUDA/pair_lj_class2_cuda.cpp +++ b/src/USER-CUDA/pair_lj_class2_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJClass2Cuda::PairLJClass2Cuda(LAMMPS *lmp) : PairLJClass2(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_cut_coul_cut_cuda.cpp b/src/USER-CUDA/pair_lj_cut_coul_cut_cuda.cpp index ce2c36bc27..ac80ff5214 100644 --- a/src/USER-CUDA/pair_lj_cut_coul_cut_cuda.cpp +++ b/src/USER-CUDA/pair_lj_cut_coul_cut_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCutCoulCutCuda::PairLJCutCoulCutCuda(LAMMPS *lmp) : PairLJCutCoulCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -123,7 +120,7 @@ void PairLJCutCoulCutCuda::coeff(int narg, char **arg) void PairLJCutCoulCutCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut/cuda requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/cut/cuda requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; diff --git a/src/USER-CUDA/pair_lj_cut_coul_debye_cuda.cpp b/src/USER-CUDA/pair_lj_cut_coul_debye_cuda.cpp index a1e553d78d..bc9a6f33ba 100644 --- a/src/USER-CUDA/pair_lj_cut_coul_debye_cuda.cpp +++ b/src/USER-CUDA/pair_lj_cut_coul_debye_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCutCoulDebyeCuda::PairLJCutCoulDebyeCuda(LAMMPS *lmp) : PairLJCutCoulDebye(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -124,7 +121,7 @@ void PairLJCutCoulDebyeCuda::coeff(int narg, char **arg) void PairLJCutCoulDebyeCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/debye/cuda requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/debye/cuda requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; diff --git a/src/USER-CUDA/pair_lj_cut_coul_long_cuda.cpp b/src/USER-CUDA/pair_lj_cut_coul_long_cuda.cpp index 80d0f7de3f..12ea4b6d1f 100644 --- a/src/USER-CUDA/pair_lj_cut_coul_long_cuda.cpp +++ b/src/USER-CUDA/pair_lj_cut_coul_long_cuda.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -62,7 +59,7 @@ PairLJCutCoulLongCuda::PairLJCutCoulLongCuda(LAMMPS *lmp) : PairLJCutCoulLong(lm { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -128,7 +125,7 @@ void PairLJCutCoulLongCuda::coeff(int narg, char **arg) void PairLJCutCoulLongCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/long requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q"); // request regular or rRESPA neighbor lists int irequest; @@ -182,15 +179,15 @@ void PairLJCutCoulLongCuda::init_style() cut_respa = ((Respa *) update->integrate)->cutoff; else cut_respa = NULL; - if (force->newton) error->warning("Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); + if (force->newton) error->warning(FLERR,"Pair style uses does not use \"newton\" setting. You might test if \"newton off\" makes the simulation run faster."); if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; cuda->shared_data.pair.g_ewald=g_ewald; cuda->shared_data.pppm.qqrd2e=force->qqrd2e; - if(ncoultablebits) error->warning("# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); + if(ncoultablebits) error->warning(FLERR,"# CUDA: You asked for the useage of Coulomb Tables. This is not supported in CUDA Pair forces. Setting is ignored.\n"); } void PairLJCutCoulLongCuda::init_list(int id, NeighList *ptr) diff --git a/src/USER-CUDA/pair_lj_cut_cuda.cpp b/src/USER-CUDA/pair_lj_cut_cuda.cpp index 29dfbb8145..c865f21361 100644 --- a/src/USER-CUDA/pair_lj_cut_cuda.cpp +++ b/src/USER-CUDA/pair_lj_cut_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCutCuda::PairLJCutCuda(LAMMPS *lmp) : PairLJCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_cut_experimental_cuda.cpp b/src/USER-CUDA/pair_lj_cut_experimental_cuda.cpp index a8700008d6..50dfaa5fa9 100644 --- a/src/USER-CUDA/pair_lj_cut_experimental_cuda.cpp +++ b/src/USER-CUDA/pair_lj_cut_experimental_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCutExperimentalCuda::PairLJCutExperimentalCuda(LAMMPS *lmp) : PairLJCut(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_expand_cuda.cpp b/src/USER-CUDA/pair_lj_expand_cuda.cpp index f06f227aff..79f5f77c80 100644 --- a/src/USER-CUDA/pair_lj_expand_cuda.cpp +++ b/src/USER-CUDA/pair_lj_expand_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJExpandCuda::PairLJExpandCuda(LAMMPS *lmp) : PairLJExpand(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_gromacs_coul_gromacs_cuda.cpp b/src/USER-CUDA/pair_lj_gromacs_coul_gromacs_cuda.cpp index 8e05acc4f1..862d180e96 100644 --- a/src/USER-CUDA/pair_lj_gromacs_coul_gromacs_cuda.cpp +++ b/src/USER-CUDA/pair_lj_gromacs_coul_gromacs_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJGromacsCoulGromacsCuda::PairLJGromacsCoulGromacsCuda(LAMMPS *lmp) : PairLJGromacsCoulGromacs(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; @@ -140,7 +137,7 @@ void PairLJGromacsCoulGromacsCuda::coeff(int narg, char **arg) void PairLJGromacsCoulGromacsCuda::init_style() { if (!atom->q_flag) - error->all("Pair style lj/gromacs/coul/gromacs requires atom attribute q"); + error->all(FLERR,"Pair style lj/gromacs/coul/gromacs requires atom attribute q"); // request regular or rRESPA neighbor lists if(atom->molecular) @@ -156,7 +153,7 @@ void PairLJGromacsCoulGromacsCuda::init_style() neighbor->requests[irequest]->cudable = 1; if (cut_lj_inner >= cut_lj || cut_coul_inner >= cut_coul) - error->all("Pair inner cutoff >= Pair outer cutoff"); + error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_ljsq = cut_lj * cut_lj; diff --git a/src/USER-CUDA/pair_lj_gromacs_cuda.cpp b/src/USER-CUDA/pair_lj_gromacs_cuda.cpp index 97bf05aac4..518ab56325 100644 --- a/src/USER-CUDA/pair_lj_gromacs_cuda.cpp +++ b/src/USER-CUDA/pair_lj_gromacs_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJGromacsCuda::PairLJGromacsCuda(LAMMPS *lmp) : PairLJGromacs(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_lj_smooth_cuda.cpp b/src/USER-CUDA/pair_lj_smooth_cuda.cpp index 25f2c5059a..84a4d9086a 100644 --- a/src/USER-CUDA/pair_lj_smooth_cuda.cpp +++ b/src/USER-CUDA/pair_lj_smooth_cuda.cpp @@ -46,16 +46,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJSmoothCuda::PairLJSmoothCuda(LAMMPS *lmp) : PairLJSmooth(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pair_morse_cuda.cpp b/src/USER-CUDA/pair_morse_cuda.cpp index befacd3413..ec2375fb92 100644 --- a/src/USER-CUDA/pair_morse_cuda.cpp +++ b/src/USER-CUDA/pair_morse_cuda.cpp @@ -61,16 +61,13 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairMorseCuda::PairMorseCuda(LAMMPS *lmp) : PairMorse(lmp) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); allocated2 = false; cuda->shared_data.pair.cudable_force = 1; diff --git a/src/USER-CUDA/pppm_cuda.cpp b/src/USER-CUDA/pppm_cuda.cpp index ffa5d17974..8167eb1d72 100644 --- a/src/USER-CUDA/pppm_cuda.cpp +++ b/src/USER-CUDA/pppm_cuda.cpp @@ -70,9 +70,6 @@ using namespace LAMMPS_NS; #define LARGE 10000.0 #define EPS_HOC 1.0e-7 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - void printArray(double* data,int nx, int ny, int nz) { @@ -102,11 +99,11 @@ PPPMCuda::PPPMCuda(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, (narg==2?1:nar { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); - if ((narg > 3)||(narg<1)) error->all("Illegal kspace_style pppm/cuda command"); + if ((narg > 3)||(narg<1)) error->all(FLERR,"Illegal kspace_style pppm/cuda command"); #ifndef FFT_CUFFT - error->all("Using kspace_style pppm/cuda without cufft is not possible. Compile with cufft=1 to include cufft. Aborting."); + error->all(FLERR,"Using kspace_style pppm/cuda without cufft is not possible. Compile with cufft=1 to include cufft. Aborting."); #endif precision = atof(arg[0]); if(narg>1) @@ -213,23 +210,23 @@ void PPPMCuda::init() // error check if (domain->triclinic) - error->all("Cannot (yet) use PPPMCuda with triclinic box"); - if (domain->dimension == 2) error->all("Cannot use PPPMCuda with 2d simulation"); + error->all(FLERR,"Cannot (yet) use PPPMCuda with triclinic box"); + if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPMCuda with 2d simulation"); - if (!atom->q_flag) error->all("Kspace style requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with PPPMCuda"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMCuda"); if (slabflag == 1) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab PPPMCuda"); + error->all(FLERR,"Incorrect boundaries with slab PPPMCuda"); } if (order > MAXORDER) { char str[128]; sprintf(str,"PPPMCuda order cannot be greater than %d",MAXORDER); - error->all(str); + error->all(FLERR,str); } // free all arrays previously allocated @@ -240,11 +237,11 @@ void PPPMCuda::init() qqrd2e = force->qqrd2e; if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); int itmp=0; double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); if (p_cutoff == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); cutoff = *p_cutoff; // if kspace is TIP4P, extract TIP4P params from pair style @@ -253,14 +250,14 @@ void PPPMCuda::init() if (strcmp(force->kspace_style,"pppm/tip4p") == 0) { if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); double *p_qdist = (double *) force->pair->extract("qdist",itmp); int *p_typeO = (int *) force->pair->extract("typeO",itmp); int *p_typeH = (int *) force->pair->extract("typeH",itmp); int *p_typeA = (int *) force->pair->extract("typeA",itmp); int *p_typeB = (int *) force->pair->extract("typeB",itmp); if (!p_qdist || !p_typeO || !p_typeH || !p_typeA || !p_typeB) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); qdist = *p_qdist; typeO = *p_typeO; typeH = *p_typeH; @@ -268,7 +265,7 @@ void PPPMCuda::init() int typeB = *p_typeB; if (force->angle == NULL || force->bond == NULL) - error->all("Bond and angle potentials must be defined for TIP4P"); + error->all(FLERR,"Bond and angle potentials must be defined for TIP4P"); double theta = force->angle->equilibrium_angle(typeA); double blen = force->bond->equilibrium_distance(typeB); alpha = qdist / (2.0 * cos(0.5*theta) * blen); @@ -289,11 +286,11 @@ void PPPMCuda::init() qsqsum = tmp; if (qsqsum == 0.0) - error->all("Cannot use kspace solver on system with no charge"); + error->all(FLERR,"Cannot use kspace solver on system with no charge"); if (fabs(qsum) > SMALL && me == 0) { char str[128]; sprintf(str,"System is not charge neutral, net charge = %g",qsum); - error->warning(str); + error->warning(FLERR,str); } // setup FFT grid resolution and g_ewald @@ -305,14 +302,14 @@ void PPPMCuda::init() while (order > 0) { if (iteration && me == 0) - error->warning("Reducing PPPMCuda order b/c stencil extends " + error->warning(FLERR,"Reducing PPPMCuda order b/c stencil extends " "beyond neighbor processor"); iteration++; set_grid(); if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) - error->all("PPPMCuda grid is too large"); + error->all(FLERR,"PPPMCuda grid is too large"); // global indices of PPPMCuda grid range from 0 to N-1 // nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of @@ -484,7 +481,7 @@ void PPPMCuda::init() order--; } - if (order == 0) error->all("PPPMCuda order has been reduced to 0"); + if (order == 0) error->all(FLERR,"PPPMCuda order has been reduced to 0"); //printf("PPPMCuda: order is %i\n"); @@ -1395,7 +1392,7 @@ void PPPMCuda::set_grid() g_ewald = gew2; fmid = diffpr(h_x,h_y,h_z,q2,acons); - if (f*fmid >= 0.0) error->all("Cannot compute PPPMCuda G"); + if (f*fmid >= 0.0) error->all(FLERR,"Cannot compute PPPMCuda G"); rtb = f < 0.0 ? (dgew=gew2-gew1,gew1) : (dgew=gew1-gew2,gew2); ncount = 0; while (fabs(dgew) > SMALL && fmid != 0.0) { @@ -1404,7 +1401,7 @@ void PPPMCuda::set_grid() fmid = diffpr(h_x,h_y,h_z,q2,acons); if (fmid <= 0.0) rtb = g_ewald; ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPMCuda G"); + if (ncount > LARGE) error->all(FLERR,"Cannot compute PPPMCuda G"); } } @@ -1449,7 +1446,7 @@ void PPPMCuda::make_power_of_prime(int* n) { if((precisionmodify!='+')&&(precisionmodify!='-')&&(precisionmodify!='c')) - {error->all("Unknown Option for PPPMCuda, assumeing '='");return;} + {error->all(FLERR,"Unknown Option for PPPMCuda, assumeing '='");return;} int oldn=*n; int* primelist=new int[1000]; int count=0; @@ -1555,7 +1552,7 @@ void PPPMCuda::particle_map() int flag_all; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Out of range atoms - cannot compute PPPMCuda!"); + if (flag_all) error->all(FLERR,"Out of range atoms - cannot compute PPPMCuda!"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp index 1a75e55de3..0c3f675fae 100644 --- a/src/USER-CUDA/verlet_cuda.cpp +++ b/src/USER-CUDA/verlet_cuda.cpp @@ -21,7 +21,6 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ - #include #include #include @@ -55,14 +54,12 @@ using namespace LAMMPS_NS; -#define MAX(a, b) ((a)>(b) ? (a) : (b)) #define MAKETIMEING - VerletCuda::VerletCuda(LAMMPS *lmp, int narg, char **arg) : Verlet(lmp, narg, arg) { cuda = lmp->cuda; if(cuda == NULL) - error->all("You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); modify_cuda=(ModifyCuda*) modify; } @@ -541,17 +538,17 @@ void VerletCuda::run(int n) if(cuda->shared_data.me==0) { if((not cuda->shared_data.pair.cudable_force)&&(force->pair)) - error->warning("# CUDA: You asked for a Verlet integration using Cuda, " + error->warning(FLERR,"# CUDA: You asked for a Verlet integration using Cuda, " "but selected a pair force which has not yet been ported to Cuda"); if((not cuda->shared_data.pppm.cudable_force)&&(force->kspace)) - error->warning("# CUDA: You asked for a Verlet integration using Cuda, " + error->warning(FLERR,"# CUDA: You asked for a Verlet integration using Cuda, " "but selected a kspace force which has not yet been ported to Cuda"); if(modify_cuda->n_post_integrate_host+modify_cuda->n_pre_exchange_host+modify_cuda->n_pre_neighbor_host+modify_cuda->n_pre_force_host+modify_cuda->n_post_force_host+modify_cuda->n_end_of_step_host+modify_cuda->n_initial_integrate_host+modify_cuda->n_final_integrate_host) - error->warning("# CUDA: You asked for a Verlet integration using Cuda, " + error->warning(FLERR,"# CUDA: You asked for a Verlet integration using Cuda, " "but several fixes have not yet been ported to Cuda.\n" "This can cause a severe speed penalty due to frequent data synchronization between host and GPU."); if(atom->firstgroupname) - error->warning("Warning: firstgroupname is used, this will cause additional data transfers."); + error->warning(FLERR,"Warning: firstgroupname is used, this will cause additional data transfers."); } cuda->uploadAll(); diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp index c7affbc384..006de86019 100644 --- a/src/USER-EFF/atom_vec_electron.cpp +++ b/src/USER-EFF/atom_vec_electron.cpp @@ -757,11 +757,11 @@ void AtomVecElectron::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[2]); spin[nlocal] = atoi(values[3]); @@ -793,7 +793,7 @@ int AtomVecElectron::data_atom_hybrid(int nlocal, char **values) spin[nlocal] = atoi(values[1]); eradius[nlocal] = atof(values[2]); if (eradius[nlocal] < 0.0) - error->one("Invalid eradius in Atoms section of data file"); + error->one(FLERR,"Invalid eradius in Atoms section of data file"); v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; diff --git a/src/USER-EFF/compute_ke_atom_eff.cpp b/src/USER-EFF/compute_ke_atom_eff.cpp index 33c900f4b3..1b68b60d22 100644 --- a/src/USER-EFF/compute_ke_atom_eff.cpp +++ b/src/USER-EFF/compute_ke_atom_eff.cpp @@ -33,7 +33,7 @@ using namespace LAMMPS_NS; ComputeKEAtomEff::ComputeKEAtomEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute ke/atom/eff command"); + if (narg != 3) error->all(FLERR,"Illegal compute ke/atom/eff command"); peratom_flag = 1; size_peratom_cols = 0; @@ -44,7 +44,7 @@ ComputeKEAtomEff::ComputeKEAtomEff(LAMMPS *lmp, int narg, char **arg) : // error check if (!atom->electron_flag) - error->all("Compute ke/atom/eff requires atom style electron"); + error->all(FLERR,"Compute ke/atom/eff requires atom style electron"); } /* ---------------------------------------------------------------------- */ @@ -62,7 +62,7 @@ void ComputeKEAtomEff::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"ke/atom/eff") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute ke/atom/eff"); + error->warning(FLERR,"More than one compute ke/atom/eff"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-EFF/compute_ke_eff.cpp b/src/USER-EFF/compute_ke_eff.cpp index 68aaa2c25b..43a2a952f8 100644 --- a/src/USER-EFF/compute_ke_eff.cpp +++ b/src/USER-EFF/compute_ke_eff.cpp @@ -32,7 +32,7 @@ using namespace LAMMPS_NS; ComputeKEEff::ComputeKEEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute ke/eff command"); + if (narg != 3) error->all(FLERR,"Illegal compute ke/eff command"); scalar_flag = 1; extscalar = 1; @@ -40,7 +40,7 @@ ComputeKEEff::ComputeKEEff(LAMMPS *lmp, int narg, char **arg) : // error check if (!atom->electron_flag) - error->all("Compute ke/eff requires atom style electron"); + error->all(FLERR,"Compute ke/eff requires atom style electron"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-EFF/compute_temp_deform_eff.cpp b/src/USER-EFF/compute_temp_deform_eff.cpp index 7bb53b9085..ccba4d782c 100644 --- a/src/USER-EFF/compute_temp_deform_eff.cpp +++ b/src/USER-EFF/compute_temp_deform_eff.cpp @@ -41,10 +41,10 @@ enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp ComputeTempDeformEff::ComputeTempDeformEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute temp/deform/eff command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp/deform/eff command"); if (!atom->electron_flag) - error->all("Compute temp/deform/eff requires atom style electron"); + error->all(FLERR,"Compute temp/deform/eff requires atom style electron"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -83,12 +83,12 @@ void ComputeTempDeformEff::init() if (strcmp(modify->fix[i]->style,"deform") == 0) { if (((FixDeform *) modify->fix[i])->remapflag == X_REMAP && comm->me == 0) - error->warning("Using compute temp/deform/eff with inconsistent " + error->warning(FLERR,"Using compute temp/deform/eff with inconsistent " "fix deform remap option"); break; } if (i == modify->nfix && comm->me == 0) - error->warning("Using compute temp/deform/eff with no fix deform defined"); + error->warning(FLERR,"Using compute temp/deform/eff with no fix deform defined"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-EFF/compute_temp_eff.cpp b/src/USER-EFF/compute_temp_eff.cpp index 4f7cc40c1b..e2089a0d60 100644 --- a/src/USER-EFF/compute_temp_eff.cpp +++ b/src/USER-EFF/compute_temp_eff.cpp @@ -36,7 +36,7 @@ ComputeTempEff::ComputeTempEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (!atom->electron_flag) - error->all("Compute temp/eff requires atom style electron"); + error->all(FLERR,"Compute temp/eff requires atom style electron"); scalar_flag = vector_flag = 1; size_vector = 6; diff --git a/src/USER-EFF/compute_temp_region_eff.cpp b/src/USER-EFF/compute_temp_region_eff.cpp index 9bcabee2a8..f43e92095f 100644 --- a/src/USER-EFF/compute_temp_region_eff.cpp +++ b/src/USER-EFF/compute_temp_region_eff.cpp @@ -36,13 +36,13 @@ ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (!atom->electron_flag) - error->all("Compute temp/region/eff requires atom style electron"); + error->all(FLERR,"Compute temp/region/eff requires atom style electron"); - if (narg != 4) error->all("Illegal compute temp/region/eff command"); + if (narg != 4) error->all(FLERR,"Illegal compute temp/region/eff command"); iregion = domain->find_region(arg[3]); if (iregion == -1) - error->all("Region ID for compute temp/region/eff does not exist"); + error->all(FLERR,"Region ID for compute temp/region/eff does not exist"); int n = strlen(arg[3]) + 1; idregion = new char[n]; strcpy(idregion,arg[3]); @@ -76,7 +76,7 @@ void ComputeTempRegionEff::init() iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for compute temp/region/eff does not exist"); + error->all(FLERR,"Region ID for compute temp/region/eff does not exist"); dof = 0.0; } diff --git a/src/USER-EFF/fix_nh_eff.cpp b/src/USER-EFF/fix_nh_eff.cpp index 70f2544c2d..e3dde84178 100644 --- a/src/USER-EFF/fix_nh_eff.cpp +++ b/src/USER-EFF/fix_nh_eff.cpp @@ -31,7 +31,7 @@ enum{NOBIAS,BIAS}; FixNHEff::FixNHEff(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (!atom->electron_flag) - error->all("Fix nvt/nph/npt/eff requires atom style electron"); + error->all(FLERR,"Fix nvt/nph/npt/eff requires atom style electron"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-EFF/fix_nph_eff.cpp b/src/USER-EFF/fix_nph_eff.cpp index 98f76c346c..7cf5be647d 100644 --- a/src/USER-EFF/fix_nph_eff.cpp +++ b/src/USER-EFF/fix_nph_eff.cpp @@ -24,9 +24,9 @@ FixNPHEff::FixNPHEff(LAMMPS *lmp, int narg, char **arg) : FixNHEff(lmp, narg, arg) { if (tstat_flag) - error->all("Temperature control can not be used with fix nph/eff"); + error->all(FLERR,"Temperature control can not be used with fix nph/eff"); if (!pstat_flag) - error->all("Pressure control must be used with fix nph/eff"); + error->all(FLERR,"Pressure control must be used with fix nph/eff"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/USER-EFF/fix_npt_eff.cpp b/src/USER-EFF/fix_npt_eff.cpp index d71a25d461..3b27e9b967 100644 --- a/src/USER-EFF/fix_npt_eff.cpp +++ b/src/USER-EFF/fix_npt_eff.cpp @@ -24,9 +24,9 @@ FixNPTEff::FixNPTEff(LAMMPS *lmp, int narg, char **arg) : FixNHEff(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix npt/eff"); + error->all(FLERR,"Temperature control must be used with fix npt/eff"); if (!pstat_flag) - error->all("Pressure control must be used with fix npt/eff"); + error->all(FLERR,"Pressure control must be used with fix npt/eff"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/USER-EFF/fix_nve_eff.cpp b/src/USER-EFF/fix_nve_eff.cpp index 392f6b7862..1466c777df 100644 --- a/src/USER-EFF/fix_nve_eff.cpp +++ b/src/USER-EFF/fix_nve_eff.cpp @@ -34,7 +34,7 @@ FixNVEEff::FixNVEEff(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (!atom->electron_flag) - error->all("Fix nve/eff requires atom style electron"); + error->all(FLERR,"Fix nve/eff requires atom style electron"); time_integrate = 1; } diff --git a/src/USER-EFF/fix_nvt_eff.cpp b/src/USER-EFF/fix_nvt_eff.cpp index b742b66ee3..a40cd4aefa 100644 --- a/src/USER-EFF/fix_nvt_eff.cpp +++ b/src/USER-EFF/fix_nvt_eff.cpp @@ -26,9 +26,9 @@ FixNVTEff::FixNVTEff(LAMMPS *lmp, int narg, char **arg) : FixNHEff(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt/eff"); + error->all(FLERR,"Temperature control must be used with fix nvt/eff"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt/eff"); + error->all(FLERR,"Pressure control can not be used with fix nvt/eff"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/USER-EFF/fix_nvt_sllod_eff.cpp b/src/USER-EFF/fix_nvt_sllod_eff.cpp index 435d70c20c..0d38c19049 100644 --- a/src/USER-EFF/fix_nvt_sllod_eff.cpp +++ b/src/USER-EFF/fix_nvt_sllod_eff.cpp @@ -33,9 +33,9 @@ FixNVTSllodEff::FixNVTSllodEff(LAMMPS *lmp, int narg, char **arg) : FixNHEff(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt/sllod/eff"); + error->all(FLERR,"Temperature control must be used with fix nvt/sllod/eff"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt/sllod/eff"); + error->all(FLERR,"Pressure control can not be used with fix nvt/sllod/eff"); // default values @@ -66,7 +66,7 @@ void FixNVTSllodEff::init() FixNHEff::init(); if (!temperature->tempbias) - error->all("Temperature for fix nvt/sllod/eff does not have a bias"); + error->all(FLERR,"Temperature for fix nvt/sllod/eff does not have a bias"); nondeformbias = 0; if (strcmp(temperature->style,"temp/deform/eff") != 0) nondeformbias = 1; @@ -77,12 +77,12 @@ void FixNVTSllodEff::init() for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"deform") == 0) { if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP) - error->all("Using fix nvt/sllod/eff with inconsistent fix deform " + error->all(FLERR,"Using fix nvt/sllod/eff with inconsistent fix deform " "remap option"); break; } if (i == modify->nfix) - error->all("Using fix nvt/sllod/eff with no fix deform defined"); + error->all(FLERR,"Using fix nvt/sllod/eff with no fix deform defined"); } diff --git a/src/USER-EFF/fix_temp_rescale_eff.cpp b/src/USER-EFF/fix_temp_rescale_eff.cpp index e5a0d19be7..b6f4d585f7 100644 --- a/src/USER-EFF/fix_temp_rescale_eff.cpp +++ b/src/USER-EFF/fix_temp_rescale_eff.cpp @@ -39,10 +39,10 @@ enum{NOBIAS,BIAS}; FixTempRescaleEff::FixTempRescaleEff(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 8) error->all("Illegal fix temp/rescale/eff command"); + if (narg < 8) error->all(FLERR,"Illegal fix temp/rescale/eff command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix temp/rescale/eff command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix temp/rescale/eff command"); scalar_flag = 1; global_freq = nevery; @@ -98,7 +98,7 @@ void FixTempRescaleEff::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/rescale/eff does not exist"); + error->all(FLERR,"Temperature ID for fix temp/rescale/eff does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -111,7 +111,7 @@ void FixTempRescaleEff::end_of_step() { double t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/rescale/eff cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/rescale/eff cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -167,7 +167,7 @@ void FixTempRescaleEff::end_of_step() int FixTempRescaleEff::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp/eff") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -178,13 +178,13 @@ int FixTempRescaleEff::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/USER-EFF/pair_eff_cut.cpp b/src/USER-EFF/pair_eff_cut.cpp index 85d2a1d1af..8f99134239 100644 --- a/src/USER-EFF/pair_eff_cut.cpp +++ b/src/USER-EFF/pair_eff_cut.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairEffCut::PairEffCut(LAMMPS *lmp) : Pair(lmp) @@ -694,7 +691,7 @@ void PairEffCut::allocate() void PairEffCut::settings(int narg, char **arg) { if (narg != 1 && narg != 3 && narg != 4 && narg != 7) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); // Defaults ECP parameters for Si PAULI_CORE_A = 0.320852; @@ -714,7 +711,7 @@ void PairEffCut::settings(int narg, char **arg) limit_size_flag = 0; flexible_pressure_flag = 0; if (strcmp(arg[1],"ecp") != 0) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); else { PAULI_CORE_A = force->numeric(arg[2]); PAULI_CORE_B = force->numeric(arg[3]); @@ -725,7 +722,7 @@ void PairEffCut::settings(int narg, char **arg) limit_size_flag = force->inumeric(arg[1]); flexible_pressure_flag = force->inumeric(arg[2]); if (strcmp(arg[3],"ecp") != 0) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); else { PAULI_CORE_A = force->numeric(arg[4]); PAULI_CORE_B = force->numeric(arg[5]); @@ -740,7 +737,7 @@ void PairEffCut::settings(int narg, char **arg) } else if (force->qqr2e==1.0) { // electron units h2e = 1.0; hhmss2e = 1.0; - } else error->all("Check your units"); + } else error->all(FLERR,"Check your units"); // reset cutoffs that have been explicitly set @@ -758,7 +755,7 @@ void PairEffCut::settings(int narg, char **arg) void PairEffCut::coeff(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all("Incorrect args for pair coefficients"); + if (narg < 2 || narg > 3) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -777,7 +774,7 @@ void PairEffCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -790,7 +787,7 @@ void PairEffCut::init_style() if (!atom->q_flag || !atom->spin_flag || !atom->eradius_flag || !atom->erforce_flag) - error->all("Pair eff/cut requires atom attributes " + error->all(FLERR,"Pair eff/cut requires atom attributes " "q, spin, eradius, erforce"); // add hook to minimizer for eradius and erforce @@ -802,7 +799,7 @@ void PairEffCut::init_style() if (update->whichflag == 1) { if (force->qqr2e == 332.06371 && update->dt == 1.0) - error->all("You must lower the default real units timestep for pEFF "); + error->all(FLERR,"You must lower the default real units timestep for pEFF "); } // need a half neigh list and optionally a granular history neigh list diff --git a/src/USER-EWALDN/ewald_n.cpp b/src/USER-EWALDN/ewald_n.cpp index d45b90f05d..ed05ca5044 100644 --- a/src/USER-EWALDN/ewald_n.cpp +++ b/src/USER-EWALDN/ewald_n.cpp @@ -44,7 +44,7 @@ enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // same as in pair.cpp EwaldN::EwaldN(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) { - if (narg!=1) error->all(KSPACE_ILLEGAL); + if (narg!=1) error->all(FLERR,KSPACE_ILLEGAL); precision = fabs(atof(arg[0])); memset(function, 0, EWALD_NORDER*sizeof(int)); kenergy = kvirial = NULL; @@ -78,13 +78,13 @@ void EwaldN::init() } if (domain->dimension == 2) // check for errors - error->all("Cannot use EwaldN with 2d simulation"); + error->all(FLERR,"Cannot use EwaldN with 2d simulation"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with EwaldN"); + error->all(FLERR,"Cannot use nonperiodic boundaries with EwaldN"); if (slabflag == 1) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab EwaldN"); + error->all(FLERR,"Incorrect boundaries with slab EwaldN"); } qqrd2e = force->qqrd2e; // check pair_style @@ -98,7 +98,7 @@ void EwaldN::init() int *ptr = pair ? (int *) pair->extract("ewald_order",tmp) : NULL; double *cutoff = pair ? (double *) pair->extract("cut_coul",tmp) : NULL; if (!(ptr||cutoff)) - error->all("KSpace style is incompatible with Pair style"); + error->all(FLERR,"KSpace style is incompatible with Pair style"); int ewald_order = ptr ? *((int *) ptr) : 1<<1; int ewald_mix = ptr ? *((int *) pair->extract("ewald_mix",tmp)) : GEOMETRIC; memset(function, 0, EWALD_NFUNCS*sizeof(int)); @@ -115,10 +115,10 @@ void EwaldN::init() if (ewald_mix==GEOMETRIC) { k = 1; break; } else if (ewald_mix==ARITHMETIC) { k = 2; break; } sprintf(str, "%s pair_style %s", KSPACE_MIX, force->pair_style); - error->all(str); + error->all(FLERR,str); default: sprintf(str, "%s pair_style %s", KSPACE_ORDER, force->pair_style); - error->all(str); + error->all(FLERR,str); } nfunctions += function[k] = 1; nsums += n[k]; @@ -309,7 +309,7 @@ void EwaldN::init_coeffs() // local pair coeffs double **epsilon = (double **) force->pair->extract("epsilon",tmp); double **sigma = (double **) force->pair->extract("sigma",tmp); if (!(epsilon&&sigma)) - error->all("epsilon or sigma reference not set by pair style in ewald/n"); + error->all(FLERR,"epsilon or sigma reference not set by pair style in ewald/n"); double eps_i, sigma_i, sigma_n, *bi = B = new double[7*n+7]; double c[7] = { 1.0, sqrt(6.0), sqrt(15.0), sqrt(20.0), sqrt(15.0), sqrt(6.0), 1.0}; diff --git a/src/USER-EWALDN/pair_buck_coul.cpp b/src/USER-EWALDN/pair_buck_coul.cpp index bb2f4f0ed0..74e9e56476 100644 --- a/src/USER-EWALDN/pair_buck_coul.cpp +++ b/src/USER-EWALDN/pair_buck_coul.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -72,10 +69,10 @@ void PairBuckCoul::options(char **arg, int order) char *option[] = {"long", "cut", "off", NULL}; int i; - if (!*arg) error->all(PAIR_ILLEGAL); + if (!*arg) error->all(FLERR,PAIR_ILLEGAL); for (i=0; option[i]&&strcmp(arg[0], option[i]); ++i); switch (i) { - default: error->all(PAIR_ILLEGAL); + default: error->all(FLERR,PAIR_ILLEGAL); case 0: ewald_order |= 1<all("Illegal pair_style command"); + if (narg != 3 && narg != 4) error->all(FLERR,"Illegal pair_style command"); ewald_order = 0; ewald_off = 0; options(arg, 6); options(++arg, 1); - if (!comm->me && ewald_order&(1<<6)) error->warning(PAIR_MIX); - if (!comm->me && ewald_order==((1<<1)|(1<<6))) error->warning(PAIR_LARGEST); - if (!*(++arg)) error->all(PAIR_MISSING); - if (ewald_off&(1<<6)) error->all(PAIR_LJ_OFF); - if (!((ewald_order^ewald_off)&(1<<1))) error->all(PAIR_COUL_CUT); + if (!comm->me && ewald_order&(1<<6)) error->warning(FLERR,PAIR_MIX); + if (!comm->me && ewald_order==((1<<1)|(1<<6))) error->warning(FLERR,PAIR_LARGEST); + if (!*(++arg)) error->all(FLERR,PAIR_MISSING); + if (ewald_off&(1<<6)) error->all(FLERR,PAIR_LJ_OFF); + if (!((ewald_order^ewald_off)&(1<<1))) error->all(FLERR,PAIR_COUL_CUT); cut_buck_global = force->numeric(*(arg++)); - if (*arg&&(ewald_order&0x42==0x42)) error->all(PAIR_CUTOFF); + if (*arg&&(ewald_order&0x42==0x42)) error->all(FLERR,PAIR_CUTOFF); if (narg == 4) cut_coul = force->numeric(*arg); else cut_coul = cut_buck_global; @@ -191,7 +188,7 @@ void *PairBuckCoul::extract(char *id, int &dim) void PairBuckCoul::coeff(int narg, char **arg) { - if (narg < 5 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -217,7 +214,7 @@ void PairBuckCoul::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -230,7 +227,7 @@ void PairBuckCoul::init_style() // require an atom style with charge defined if (!atom->q_flag && (ewald_order&(1<<1))) - error->all( + error->all(FLERR, "Invoking coulombic in pair style lj/coul requires atom attribute q"); // request regular or rRESPA neighbor lists @@ -282,12 +279,12 @@ void PairBuckCoul::init_style() if (ewald_order&(1<<1)) { // r^-1 kspace if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; } if (ewald_order&(1<<6)) { // r^-6 kspace if (!force->kspace && strcmp(force->kspace_style,"ewald/n")) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); g_ewald = force->kspace->g_ewald; } @@ -315,7 +312,7 @@ void PairBuckCoul::init_list(int id, NeighList *ptr) double PairBuckCoul::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); cut_buck[i][j] = cut_buck_read[i][j]; buck_a[i][j] = buck_a_read[i][j]; @@ -333,7 +330,7 @@ double PairBuckCoul::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && MIN(cut_buck[i][j],cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); if (offset_flag) { double rexp = exp(-cut_buck[i][j]/buck_rho[i][j]); diff --git a/src/USER-EWALDN/pair_lj_coul.cpp b/src/USER-EWALDN/pair_lj_coul.cpp index b6ee94bbda..4e1692680f 100644 --- a/src/USER-EWALDN/pair_lj_coul.cpp +++ b/src/USER-EWALDN/pair_lj_coul.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -71,10 +68,10 @@ void PairLJCoul::options(char **arg, int order) char *option[] = {"long", "cut", "off", NULL}; int i; - if (!*arg) error->all(PAIR_ILLEGAL); + if (!*arg) error->all(FLERR,PAIR_ILLEGAL); for (i=0; option[i]&&strcmp(arg[0], option[i]); ++i); switch (i) { - default: error->all(PAIR_ILLEGAL); + default: error->all(FLERR,PAIR_ILLEGAL); case 0: ewald_order |= 1<all("Illegal pair_style command"); + if (narg != 3 && narg != 4) error->all(FLERR,"Illegal pair_style command"); ewald_off = 0; ewald_order = 0; options(arg, 6); options(++arg, 1); - if (!comm->me && ewald_order&(1<<6)) error->warning(PAIR_MIX); - if (!comm->me && ewald_order==((1<<1)|(1<<6))) error->warning(PAIR_LARGEST); - if (!*(++arg)) error->all(PAIR_MISSING); - if (!((ewald_order^ewald_off)&(1<<1))) error->all(PAIR_COUL_CUT); + if (!comm->me && ewald_order&(1<<6)) error->warning(FLERR,PAIR_MIX); + if (!comm->me && ewald_order==((1<<1)|(1<<6))) error->warning(FLERR,PAIR_LARGEST); + if (!*(++arg)) error->all(FLERR,PAIR_MISSING); + if (!((ewald_order^ewald_off)&(1<<1))) error->all(FLERR,PAIR_COUL_CUT); cut_lj_global = force->numeric(*(arg++)); - if (*arg&&(ewald_order&0x42==0x42)) error->all(PAIR_CUTOFF); + if (*arg&&(ewald_order&0x42==0x42)) error->all(FLERR,PAIR_CUTOFF); if (narg == 4) cut_coul = force->numeric(*arg); else cut_coul = cut_lj_global; @@ -188,7 +185,7 @@ void *PairLJCoul::extract(char *id, int &dim) void PairLJCoul::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -212,7 +209,7 @@ void PairLJCoul::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -228,7 +225,7 @@ void PairLJCoul::init_style() // require an atom style with charge defined if (!atom->q_flag && (ewald_order&(1<<1))) - error->all( + error->all(FLERR, "Invoking coulombic in pair style lj/coul requires atom attribute q"); // request regular or rRESPA neighbor lists @@ -280,15 +277,15 @@ void PairLJCoul::init_style() if (ewald_order&(1<<1)) { // r^-1 kspace if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); for (i=0; style1[i]&&strcmp(force->kspace_style, style1[i]); ++i); - if (!style1[i]) error->all("Pair style is incompatible with KSpace style"); + if (!style1[i]) error->all(FLERR,"Pair style is incompatible with KSpace style"); } if (ewald_order&(1<<6)) { // r^-6 kspace if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); + error->all(FLERR,"Pair style is incompatible with KSpace style"); for (i=0; style6[i]&&strcmp(force->kspace_style, style6[i]); ++i); - if (!style6[i]) error->all("Pair style is incompatible with KSpace style"); + if (!style6[i]) error->all(FLERR,"Pair style is incompatible with KSpace style"); } if (force->kspace) g_ewald = force->kspace->g_ewald; @@ -343,7 +340,7 @@ double PairLJCoul::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && MIN(cut_lj[i][j],cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); if (offset_flag) { double ratio = sigma[i][j] / cut_lj[i][j]; diff --git a/src/USER-MISC/angle_cosine_shift.cpp b/src/USER-MISC/angle_cosine_shift.cpp index 4c6c7cf74a..2fa2ad2b96 100644 --- a/src/USER-MISC/angle_cosine_shift.cpp +++ b/src/USER-MISC/angle_cosine_shift.cpp @@ -168,7 +168,7 @@ void AngleCosineShift::allocate() void AngleCosineShift::coeff(int narg, char **arg) { - if (narg != 3) error->all("Incorrect args for angle coefficients"); + if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -190,7 +190,7 @@ void AngleCosineShift::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/angle_cosine_shift_exp.cpp b/src/USER-MISC/angle_cosine_shift_exp.cpp index 7cbfd5bcfc..cd6a4960d9 100644 --- a/src/USER-MISC/angle_cosine_shift_exp.cpp +++ b/src/USER-MISC/angle_cosine_shift_exp.cpp @@ -190,7 +190,7 @@ void AngleCosineShiftExp::allocate() void AngleCosineShiftExp::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for angle coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for angle coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -215,7 +215,7 @@ void AngleCosineShiftExp::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for angle coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/bond_harmonic_shift.cpp b/src/USER-MISC/bond_harmonic_shift.cpp index b051c7dff5..958dad69f8 100644 --- a/src/USER-MISC/bond_harmonic_shift.cpp +++ b/src/USER-MISC/bond_harmonic_shift.cpp @@ -125,7 +125,7 @@ void BondHarmonicShift::allocate() void BondHarmonicShift::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for bond coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -144,7 +144,7 @@ void BondHarmonicShift::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-MISC/bond_harmonic_shift_cut.cpp b/src/USER-MISC/bond_harmonic_shift_cut.cpp index 68f622488f..da78a54aed 100644 --- a/src/USER-MISC/bond_harmonic_shift_cut.cpp +++ b/src/USER-MISC/bond_harmonic_shift_cut.cpp @@ -126,7 +126,7 @@ void BondHarmonicShiftCut::allocate() void BondHarmonicShiftCut::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for bond coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -145,7 +145,7 @@ void BondHarmonicShiftCut::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for bond coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-MISC/compute_ackland_atom.cpp b/src/USER-MISC/compute_ackland_atom.cpp index fa50b5f9d2..33b2d8a8e0 100644 --- a/src/USER-MISC/compute_ackland_atom.cpp +++ b/src/USER-MISC/compute_ackland_atom.cpp @@ -40,7 +40,7 @@ enum{UNKNOWN,BCC,FCC,HCP,ICO}; ComputeAcklandAtom::ComputeAcklandAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute ackland/atom command"); + if (narg != 3) error->all(FLERR,"Illegal compute ackland/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -82,7 +82,7 @@ void ComputeAcklandAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"ackland/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute ackland/atom"); + error->warning(FLERR,"More than one compute ackland/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/compute_temp_rotate.cpp b/src/USER-MISC/compute_temp_rotate.cpp index 60f704e4e2..539683f4f4 100644 --- a/src/USER-MISC/compute_temp_rotate.cpp +++ b/src/USER-MISC/compute_temp_rotate.cpp @@ -32,15 +32,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ ComputeTempRotate::ComputeTempRotate(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute temp/rotate command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp/rotate command"); scalar_flag = vector_flag = 1; size_vector = 6; diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.cpp b/src/USER-MISC/dihedral_cosine_shift_exp.cpp index 88258b430c..29e15fe6ce 100644 --- a/src/USER-MISC/dihedral_cosine_shift_exp.cpp +++ b/src/USER-MISC/dihedral_cosine_shift_exp.cpp @@ -144,7 +144,7 @@ void DihedralCosineShiftExp::compute(int eflag, int vflag) sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str,0); + error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", @@ -273,7 +273,7 @@ void DihedralCosineShiftExp::allocate() void DihedralCosineShiftExp::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for dihedral coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; @@ -298,7 +298,7 @@ void DihedralCosineShiftExp::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for dihedral coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-MISC/fix_addtorque.cpp b/src/USER-MISC/fix_addtorque.cpp index e12a4658b4..bf1a8b58aa 100644 --- a/src/USER-MISC/fix_addtorque.cpp +++ b/src/USER-MISC/fix_addtorque.cpp @@ -39,7 +39,7 @@ enum{NONE,CONSTANT,EQUAL,ATOM}; FixAddTorque::FixAddTorque(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix addtorque command"); + if (narg != 6) error->all(FLERR,"Illegal fix addtorque command"); scalar_flag = 1; vector_flag = 1; @@ -108,21 +108,21 @@ void FixAddTorque::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix addtorque does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; - else error->all("Variable for fix addtorque is invalid style"); + else error->all(FLERR,"Variable for fix addtorque is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix addtorque does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; - else error->all("Variable for fix addtorque is invalid style"); + else error->all(FLERR,"Variable for fix addtorque is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix addtorque does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; - else error->all("Variable for fix addtorque is invalid style"); + else error->all(FLERR,"Variable for fix addtorque is invalid style"); } if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL) diff --git a/src/USER-MISC/fix_imd.cpp b/src/USER-MISC/fix_imd.cpp index 3b34ac69b6..25b140318d 100644 --- a/src/USER-MISC/fix_imd.cpp +++ b/src/USER-MISC/fix_imd.cpp @@ -444,11 +444,11 @@ FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (narg < 4) - error->all("Illegal fix imd command"); + error->all(FLERR,"Illegal fix imd command"); imd_port = atoi(arg[3]); if (imd_port < 1024) - error->all("Illegal fix imd parameter: port < 1024"); + error->all(FLERR,"Illegal fix imd parameter: port < 1024"); /* default values for optional flags */ unwrap_flag = 0; @@ -477,17 +477,17 @@ FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) : } else if (0 == strcmp(arg[argsdone], "trate")) { imd_trate = atoi(arg[argsdone+1]); } else { - error->all("Unknown fix imd parameter"); + error->all(FLERR,"Unknown fix imd parameter"); } ++argsdone; ++argsdone; } /* sanity check on parameters */ if (imd_trate < 1) - error->all("Illegal fix imd parameter. trate < 1."); + error->all(FLERR,"Illegal fix imd parameter. trate < 1."); bigint n = group->count(igroup); - if (n > MAXSMALLINT) error->all("Too many atoms for fix imd"); + if (n > MAXSMALLINT) error->all(FLERR,"Too many atoms for fix imd"); num_coords = static_cast (n); MPI_Comm_rank(world,&me); @@ -522,7 +522,7 @@ FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) : } MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); if (imd_terminate) - error->all("LAMMPS Terminated on error in IMD."); + error->all(FLERR,"LAMMPS Terminated on error in IMD."); /* storage required to communicate a single coordinate or force. */ size_one = sizeof(struct commdata); @@ -702,7 +702,7 @@ void FixIMD::setup(int) MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world); MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); if (imd_terminate) - error->all("LAMMPS terminated on error in setting up IMD connection."); + error->all(FLERR,"LAMMPS terminated on error in setting up IMD connection."); /* initialize and build hashtable. */ inthash_t *hashtable=new inthash_t; @@ -815,7 +815,7 @@ void FixIMD::post_force(int vflag) MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world); MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); if (imd_terminate) - error->all("LAMMPS terminated on error in setting up IMD connection."); + error->all(FLERR,"LAMMPS terminated on error in setting up IMD connection."); if (imd_inactive) return; /* IMD client has detached and not yet come back. do nothing. */ } @@ -951,7 +951,7 @@ void FixIMD::post_force(int vflag) MPI_Bcast(&imd_forces, 1, MPI_INT, 0, world); MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); if (imd_terminate) - error->all("LAMMPS terminated on IMD request."); + error->all(FLERR,"LAMMPS terminated on IMD request."); if (imd_forces > 0) { /* check if we need to readjust the forces comm buffer on the receiving nodes. */ diff --git a/src/USER-MISC/fix_smd.cpp b/src/USER-MISC/fix_smd.cpp index 4d251d3fe3..836a11cd64 100644 --- a/src/USER-MISC/fix_smd.cpp +++ b/src/USER-MISC/fix_smd.cpp @@ -57,20 +57,20 @@ FixSMD::FixSMD(LAMMPS *lmp, int narg, char **arg) : int argoffs=3; if (strcmp(arg[argoffs],"cvel") == 0) { - if (narg < argoffs+3) error->all("Illegal fix smd command"); + if (narg < argoffs+3) error->all(FLERR,"Illegal fix smd command"); styleflag |= SMD_CVEL; k_smd = atof(arg[argoffs+1]); v_smd = atof(arg[argoffs+2]); // to be multiplied by update->dt when used. argoffs += 3; } else if (strcmp(arg[argoffs],"cfor") == 0) { - if (narg < argoffs+2) error->all("Illegal fix smd command"); + if (narg < argoffs+2) error->all(FLERR,"Illegal fix smd command"); styleflag |= SMD_CFOR; f_smd = atof(arg[argoffs+1]); argoffs += 2; - } else error->all("Illegal fix smd command"); + } else error->all(FLERR,"Illegal fix smd command"); if (strcmp(arg[argoffs],"tether") == 0) { - if (narg < argoffs+5) error->all("Illegal fix smd command"); + if (narg < argoffs+5) error->all(FLERR,"Illegal fix smd command"); styleflag |= SMD_TETHER; if (strcmp(arg[argoffs+1],"NULL") == 0) xflag = 0; else xc = atof(arg[argoffs+1]); @@ -79,16 +79,16 @@ FixSMD::FixSMD(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[argoffs+3],"NULL") == 0) zflag = 0; else zc = atof(arg[argoffs+3]); r0 = atof(arg[argoffs+4]); - if (r0 < 0) error->all("R0 < 0 for fix smd command"); + if (r0 < 0) error->all(FLERR,"R0 < 0 for fix smd command"); argoffs += 5; } else if (strcmp(arg[argoffs],"couple") == 0) { - if (narg < argoffs+6) error->all("Illegal fix smd command"); + if (narg < argoffs+6) error->all(FLERR,"Illegal fix smd command"); styleflag |= SMD_COUPLE; igroup2 = group->find(arg[argoffs+1]); if (igroup2 == -1) - error->all("Could not find fix smd couple group ID"); + error->all(FLERR,"Could not find fix smd couple group ID"); if (igroup2 == igroup) - error->all("Two groups cannot be the same in fix smd couple"); + error->all(FLERR,"Two groups cannot be the same in fix smd couple"); group2bit = group->bitmask[igroup2]; if (strcmp(arg[argoffs+2],"NULL") == 0) xflag = 0; @@ -102,9 +102,9 @@ FixSMD::FixSMD(LAMMPS *lmp, int narg, char **arg) : else zc = atof(arg[argoffs+4]); r0 = atof(arg[argoffs+5]); - if (r0 < 0) error->all("R0 < 0 for fix smd command"); + if (r0 < 0) error->all(FLERR,"R0 < 0 for fix smd command"); argoffs +=6; - } else error->all("Illegal fix smd command"); + } else error->all(FLERR,"Illegal fix smd command"); force_flag = 0; ftotal[0] = ftotal[1] = ftotal[2] = 0.0; diff --git a/src/USER-MISC/pair_cdeam.cpp b/src/USER-MISC/pair_cdeam.cpp index 2d0e224f1c..b2e6265a2c 100644 --- a/src/USER-MISC/pair_cdeam.cpp +++ b/src/USER-MISC/pair_cdeam.cpp @@ -41,7 +41,7 @@ using namespace LAMMPS_NS; inline void my_failure(Error* error, const char* file, int line) { char str[1024]; sprintf(str,"Assertion failure: File %s, line %i", file, line); - error->one(str); + error->one(FLERR,str); } #else #define ASSERT(cond) @@ -66,7 +66,7 @@ PairCDEAM::PairCDEAM(LAMMPS *lmp, int _cdeamVersion) : PairEAM(lmp), PairEAMAllo comm_reverse = 2; } else { - error->all("Invalid CD-EAM potential version."); + error->all(FLERR,"Invalid CD-EAM potential version."); } } @@ -202,7 +202,7 @@ void PairCDEAM::compute(int eflag, int vflag) // //for(i = 0; i < nlocal + atom->nghost; i++) { // if(rho[i] == 0 && (type[i] == speciesA || type[i] == speciesB)) - // error->one("CD-EAM potential routine: Detected atom with zero electron density."); + // error->one(FLERR,"CD-EAM potential routine: Detected atom with zero electron density."); //} // Stage II @@ -421,7 +421,7 @@ void PairCDEAM::coeff(int narg, char **arg) // Make sure the EAM file is a CD-EAM binary alloy. if(setfl->nelements < 2) - error->all("The EAM file must contain at least 2 elements to be used with the eam/cd pair style."); + error->all(FLERR,"The EAM file must contain at least 2 elements to be used with the eam/cd pair style."); // Read in the coefficients of the h polynomial from the end of the EAM file. read_h_coeff(arg[2]); @@ -434,19 +434,19 @@ void PairCDEAM::coeff(int narg, char **arg) for(int i = 1; i <= atom->ntypes; i++) { if(map[i] == 0) { if(speciesA >= 0) - error->all("The first element from the EAM file may only be mapped to a single atom type."); + error->all(FLERR,"The first element from the EAM file may only be mapped to a single atom type."); speciesA = i; } if(map[i] == 1) { if(speciesB >= 0) - error->all("The second element from the EAM file may only be mapped to a single atom type."); + error->all(FLERR,"The second element from the EAM file may only be mapped to a single atom type."); speciesB = i; } } if(speciesA < 0) - error->all("The first element from the EAM file must be mapped to exactly one atom type."); + error->all(FLERR,"The first element from the EAM file must be mapped to exactly one atom type."); if(speciesB < 0) - error->all("The second element from the EAM file must be mapped to exactly one atom type."); + error->all(FLERR,"The second element from the EAM file must be mapped to exactly one atom type."); } /* ---------------------------------------------------------------------- @@ -463,7 +463,7 @@ void PairCDEAM::read_h_coeff(char *filename) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open EAM potential file %s", filename); - error->one(str); + error->one(FLERR,str); } // h coefficients are stored at the end of the file. @@ -480,7 +480,7 @@ void PairCDEAM::read_h_coeff(char *filename) hcoeff[i++] = atof(ptr); } if(i != nhcoeff || nhcoeff < 1) - error->one("Failed to read h(x) function coefficients from EAM file."); + error->one(FLERR,"Failed to read h(x) function coefficients from EAM file."); // Close the potential file. fclose(fp); diff --git a/src/USER-MISC/pair_dipole_sf.cpp b/src/USER-MISC/pair_dipole_sf.cpp index f437571790..8adf066352 100644 --- a/src/USER-MISC/pair_dipole_sf.cpp +++ b/src/USER-MISC/pair_dipole_sf.cpp @@ -28,9 +28,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairDipoleSF::PairDipoleSF(LAMMPS *lmp) : Pair(lmp) @@ -326,7 +323,7 @@ void PairDipoleSF::allocate() void PairDipoleSF::settings(int narg, char **arg) { if (narg < 1 || narg > 2) - error->all("Incorrect args in pair_style command"); + error->all(FLERR,"Incorrect args in pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -352,7 +349,7 @@ void PairDipoleSF::settings(int narg, char **arg) void PairDipoleSF::coeff(int narg, char **arg) { if (narg < 4 || narg > 6) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -379,7 +376,7 @@ void PairDipoleSF::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -389,7 +386,7 @@ void PairDipoleSF::coeff(int narg, char **arg) void PairDipoleSF::init_style() { if (!atom->q_flag || !atom->mu_flag || !atom->torque_flag) - error->all("Pair dipole/sf requires atom attributes q, mu, torque"); + error->all(FLERR,"Pair dipole/sf requires atom attributes q, mu, torque"); neighbor->request(this); } diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp index 369877ab3d..77e5ee20da 100755 --- a/src/USER-MISC/pair_edip.cpp +++ b/src/USER-MISC/pair_edip.cpp @@ -616,7 +616,7 @@ void PairEDIP::allocate() void PairEDIP::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- */ @@ -757,12 +757,12 @@ void PairEDIP::coeff(int narg, char **arg) if (!allocated) allocate(); if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to elements in potential file // map[i] = which element the Ith atom type is, -1 if NULL @@ -815,7 +815,7 @@ void PairEDIP::coeff(int narg, char **arg) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); // allocate tables and internal structures @@ -831,9 +831,9 @@ void PairEDIP::coeff(int narg, char **arg) void PairEDIP::init_style() { if (atom->tag_enable == 0) - error->all("Pair style EDIP requires atom IDs"); + error->all(FLERR,"Pair style EDIP requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style EDIP requires newton pair on"); + error->all(FLERR,"Pair style EDIP requires newton pair on"); // need a full neighbor list @@ -848,7 +848,7 @@ void PairEDIP::init_style() double PairEDIP::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); return cutmax; } @@ -872,7 +872,7 @@ void PairEDIP::read_file(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open EDIP potential file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -923,7 +923,7 @@ void PairEDIP::read_file(char *file) } if (nwords != params_per_line) - error->all("Incorrect format in EDIP potential file"); + error->all(FLERR,"Incorrect format in EDIP potential file"); // words = ptrs to all words in line @@ -980,7 +980,7 @@ void PairEDIP::read_file(char *file) params[nparams].eta < 0.0 || params[nparams].gamm < 0.0 || params[nparams].lambda < 0.0 || params[nparams].mu < 0.0 || params[nparams].rho < 0.0 || params[nparams].sigma < 0.0) - error->all("Illegal EDIP parameter"); + error->all(FLERR,"Illegal EDIP parameter"); nparams++; } @@ -1009,11 +1009,11 @@ void PairEDIP::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all("Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all("Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry"); elem2param[i][j][k] = n; } diff --git a/src/USER-MISC/pair_lj_sf.cpp b/src/USER-MISC/pair_lj_sf.cpp index b4a278188a..633b8be2e8 100644 --- a/src/USER-MISC/pair_lj_sf.cpp +++ b/src/USER-MISC/pair_lj_sf.cpp @@ -28,9 +28,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJShiftedForce::PairLJShiftedForce(LAMMPS *lmp) : Pair(lmp) {} @@ -173,12 +170,12 @@ void PairLJShiftedForce::allocate() void PairLJShiftedForce::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); if (cut_global <= 0.0) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); // reset cutoffs that have been explicitly set @@ -196,7 +193,7 @@ void PairLJShiftedForce::settings(int narg, char **arg) void PairLJShiftedForce::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -210,7 +207,7 @@ void PairLJShiftedForce::coeff(int narg, char **arg) if (narg == 5) cut_one = force->numeric(arg[4]); if (cut_one <= 0.0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -223,7 +220,7 @@ void PairLJShiftedForce::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-REAXC/fix_qeq_reax.cpp b/src/USER-REAXC/fix_qeq_reax.cpp index 0c7784aadd..b68da226f4 100644 --- a/src/USER-REAXC/fix_qeq_reax.cpp +++ b/src/USER-REAXC/fix_qeq_reax.cpp @@ -50,15 +50,12 @@ using namespace LAMMPS_NS; #define MIN_CAP 50 #define MIN_NBRS 100 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixQEqReax::FixQEqReax(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 8) error->all("Illegal fix qeq/reax command"); + if (narg != 8) error->all(FLERR,"Illegal fix qeq/reax command"); nevery = atoi(arg[3]); swa = atof(arg[4]); @@ -148,13 +145,13 @@ void FixQEqReax::pertype_parameters(char *arg) if (strcmp(arg,"reax/c") == 0) { reaxflag = 1; Pair *pair = force->pair_match("reax/c",1); - if (pair == NULL) error->all("No pair reax/c for fix qeq/reax"); + if (pair == NULL) error->all(FLERR,"No pair reax/c for fix qeq/reax"); int tmp; chi = (double *) pair->extract("chi",tmp); eta = (double *) pair->extract("eta",tmp); gamma = (double *) pair->extract("gamma",tmp); if (chi == NULL || eta == NULL || gamma == NULL) - error->all("Fix qeq/reax could not extract params from pair reax/c"); + error->all(FLERR,"Fix qeq/reax could not extract params from pair reax/c"); return; } @@ -171,17 +168,17 @@ void FixQEqReax::pertype_parameters(char *arg) if (comm->me == 0) { if ((pf = fopen(arg,"r")) == NULL) - error->one("Fix qeq/reax parameter file could not be found"); + error->one(FLERR,"Fix qeq/reax parameter file could not be found"); for (i = 1; i <= ntypes && !feof(pf); i++) { fscanf(pf,"%d %lg %lg %lg",&itype,&v1,&v2,&v3); if (itype < 1 || itype > ntypes) - error->one("Fix qeq/reax invalid atom type in param file"); + error->one(FLERR,"Fix qeq/reax invalid atom type in param file"); chi[itype] = v1; eta[itype] = v2; gamma[itype] = v3; } - if (i <= ntypes) error->one("Invalid param file for fix qeq/reax"); + if (i <= ntypes) error->one(FLERR,"Invalid param file for fix qeq/reax"); fclose(pf); } @@ -287,7 +284,7 @@ void FixQEqReax::reallocate_matrix() void FixQEqReax::init() { - if (!atom->q_flag) error->all("Fix qeq/reax requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Fix qeq/reax requires atom attribute q"); // need a half neighbor list w/ Newton off // built whenever re-neighboring occurs @@ -333,11 +330,11 @@ void FixQEqReax::init_taper() double d7, swa2, swa3, swb2, swb3; if (fabs(swa) > 0.01 && comm->me == 0) - error->warning("Fix qeq/reax has non-zero lower Taper radius cutoff"); + error->warning(FLERR,"Fix qeq/reax has non-zero lower Taper radius cutoff"); if (swb < 0) - error->all( "Fix qeq/reax has negative upper Taper radius cutoff"); + error->all(FLERR, "Fix qeq/reax has negative upper Taper radius cutoff"); else if (swb < 5 && comm->me == 0) - error->warning("Fix qeq/reax has very low Taper radius cutoff"); + error->warning(FLERR,"Fix qeq/reax has very low Taper radius cutoff"); d7 = pow( swb - swa, 7 ); swa2 = SQR( swa ); @@ -536,8 +533,8 @@ void FixQEqReax::compute_H() char str[128]; sprintf(str,"H matrix size has been exceeded: m_fill=%d H.m=%d\n", m_fill, H.m ); - error->warning(str); - error->all("Fix qeq/reax has insufficient QEq matrix size"); + error->warning(FLERR,str); + error->all(FLERR,"Fix qeq/reax has insufficient QEq matrix size"); } } @@ -606,7 +603,7 @@ int FixQEqReax::CG( double *b, double *x ) } if (i >= 100 && comm->me == 0) - error->warning("Fix qeq/reax CG convergence failed"); + error->warning(FLERR,"Fix qeq/reax CG convergence failed"); return i; } diff --git a/src/USER-REAXC/pair_reax_c.cpp b/src/USER-REAXC/pair_reax_c.cpp index 023dc2db36..96bdb293e6 100644 --- a/src/USER-REAXC/pair_reax_c.cpp +++ b/src/USER-REAXC/pair_reax_c.cpp @@ -162,7 +162,7 @@ void PairReaxC::allocate( ) void PairReaxC::settings(int narg, char **arg) { - if (narg != 1 && narg != 3) error->all("Illegal pair_style command"); + if (narg != 1 && narg != 3) error->all(FLERR,"Illegal pair_style command"); // read name of control file or use default controls @@ -196,12 +196,12 @@ void PairReaxC::settings(int narg, char **arg) while (iarg < narg) { if (strcmp(arg[iarg],"checkqeq") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_style reax/c command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_style reax/c command"); if (strcmp(arg[iarg+1],"yes") == 0) qeqflag = 1; else if (strcmp(arg[iarg+1],"no") == 0) qeqflag = 0; - else error->all("Illegal pair_style reax/c command"); + else error->all(FLERR,"Illegal pair_style reax/c command"); iarg += 2; - } else error->all("Illegal pair_style reax/c command"); + } else error->all(FLERR,"Illegal pair_style reax/c command"); } // LAMMPS is responsible for generating nbrs @@ -216,12 +216,12 @@ void PairReaxC::coeff( int nargs, char **args ) if (!allocated) allocate(); if (nargs != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(args[0],"*") != 0 || strcmp(args[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); // read ffield file @@ -244,7 +244,7 @@ void PairReaxC::coeff( int nargs, char **args ) // error check if (itmp < 0 || itmp >= nreax_types) - error->all("Non-existent ReaxFF type"); + error->all(FLERR,"Non-existent ReaxFF type"); } @@ -257,21 +257,21 @@ void PairReaxC::coeff( int nargs, char **args ) count++; } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- */ void PairReaxC::init_style( ) { - if (!atom->q_flag) error->all("Pair reax/c requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Pair reax/c requires atom attribute q"); firstwarn = 1; int iqeq; for (iqeq = 0; iqeq < modify->nfix; iqeq++) if (strcmp(modify->fix[iqeq]->style,"qeq/reax") == 0) break; if (iqeq == modify->nfix && qeqflag == 1) - error->all("Pair reax/c requires use of fix qeq/reax"); + error->all(FLERR,"Pair reax/c requires use of fix qeq/reax"); system->n = atom->nlocal; // my atoms system->N = atom->nlocal + atom->nghost; // mine + ghosts @@ -284,9 +284,9 @@ void PairReaxC::init_style( ) system->big_box.box_norms[2] = 0; if (atom->tag_enable == 0) - error->all("Pair style reax/c requires atom IDs"); + error->all(FLERR,"Pair style reax/c requires atom IDs"); if (force->newton_pair == 0) - error->all("Pair style reax/c requires newton pair on"); + error->all(FLERR,"Pair style reax/c requires newton pair on"); // need a half neighbor list w/ Newton off // built whenever re-neighboring occurs @@ -343,7 +343,7 @@ void PairReaxC::setup( ) int num_nbrs = estimate_reax_lists(); if(!Make_List(system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, lists+FAR_NBRS, world)) - error->all("Pair reax/c problem in far neighbor list"); + error->all(FLERR,"Pair reax/c problem in far neighbor list"); write_reax_lists(); Initialize( system, control, data, workspace, &lists, out_control, @@ -398,7 +398,7 @@ void PairReaxC::compute(int eflag, int vflag) if ((eflag_atom || vflag_atom) && firstwarn) { firstwarn = 0; if (comm->me == 0) - error->warning("Pair reax/c cannot yet compute " + error->warning(FLERR,"Pair reax/c cannot yet compute " "per-atom energy or stress"); } diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp index c977a8e324..b69686824c 100644 --- a/src/USER-SPH/atom_vec_meso.cpp +++ b/src/USER-SPH/atom_vec_meso.cpp @@ -60,7 +60,7 @@ void AtomVecMeso::grow(int n) { nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag, nmax, "atom:tag"); type = memory->grow(atom->type, nmax, "atom:type"); @@ -783,11 +783,11 @@ void AtomVecMeso::data_atom(double *coord, int imagetmp, char **values) { tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); rho[nlocal] = atof(values[2]); e[nlocal] = atof(values[3]); diff --git a/src/USER-SPH/compute_meso_e_atom.cpp b/src/USER-SPH/compute_meso_e_atom.cpp index 934818584b..4ee0dce518 100644 --- a/src/USER-SPH/compute_meso_e_atom.cpp +++ b/src/USER-SPH/compute_meso_e_atom.cpp @@ -28,8 +28,8 @@ using namespace LAMMPS_NS; ComputeMesoEAtom::ComputeMesoEAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Number of arguments for compute meso_e/atom command != 3"); - if (atom->e_flag != 1) error->all("compute meso_e/atom command requires atom_style with energy (e.g. meso)"); + if (narg != 3) error->all(FLERR,"Number of arguments for compute meso_e/atom command != 3"); + if (atom->e_flag != 1) error->all(FLERR,"compute meso_e/atom command requires atom_style with energy (e.g. meso)"); peratom_flag = 1; size_peratom_cols = 0; @@ -54,7 +54,7 @@ void ComputeMesoEAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"evector/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute evector/atom"); + error->warning(FLERR,"More than one compute evector/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/compute_meso_rho_atom.cpp b/src/USER-SPH/compute_meso_rho_atom.cpp index 98aab3ad72..465bbfe164 100644 --- a/src/USER-SPH/compute_meso_rho_atom.cpp +++ b/src/USER-SPH/compute_meso_rho_atom.cpp @@ -28,8 +28,8 @@ using namespace LAMMPS_NS; ComputeMesoRhoAtom::ComputeMesoRhoAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute meso_rho/atom command"); - if (atom->rho_flag != 1) error->all("compute meso_rho/atom command requires atom_style with density (e.g. meso)"); + if (narg != 3) error->all(FLERR,"Illegal compute meso_rho/atom command"); + if (atom->rho_flag != 1) error->all(FLERR,"compute meso_rho/atom command requires atom_style with density (e.g. meso)"); peratom_flag = 1; size_peratom_cols = 0; @@ -54,7 +54,7 @@ void ComputeMesoRhoAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"rhoVector/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute rhoVector/atom"); + error->warning(FLERR,"More than one compute rhoVector/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/compute_meso_t_atom.cpp b/src/USER-SPH/compute_meso_t_atom.cpp index 21a9a4d660..5d4f1177ba 100644 --- a/src/USER-SPH/compute_meso_t_atom.cpp +++ b/src/USER-SPH/compute_meso_t_atom.cpp @@ -28,9 +28,9 @@ using namespace LAMMPS_NS; ComputeMesoTAtom::ComputeMesoTAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Number of arguments for compute meso_t/atom command != 3"); + if (narg != 3) error->all(FLERR,"Number of arguments for compute meso_t/atom command != 3"); if ((atom->e_flag != 1) || (atom->cv_flag != 1)) - error->all("compute meso_e/atom command requires atom_style with both energy and heat capacity (e.g. meso)"); + error->all(FLERR,"compute meso_e/atom command requires atom_style with both energy and heat capacity (e.g. meso)"); peratom_flag = 1; size_peratom_cols = 0; @@ -55,7 +55,7 @@ void ComputeMesoTAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"meso_t/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute meso_t/atom"); + error->warning(FLERR,"More than one compute meso_t/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SPH/fix_meso.cpp b/src/USER-SPH/fix_meso.cpp index 0b8576f386..cfab98164e 100644 --- a/src/USER-SPH/fix_meso.cpp +++ b/src/USER-SPH/fix_meso.cpp @@ -38,11 +38,11 @@ FixMeso::FixMeso(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if ((atom->e_flag != 1) || (atom->rho_flag != 1)) - error->all( + error->all(FLERR, "fix meso command requires atom_style with both energy and density"); if (narg != 3) - error->all("Illegal number of arguments for fix meso command"); + error->all(FLERR,"Illegal number of arguments for fix meso command"); time_integrate = 1; } diff --git a/src/USER-SPH/fix_meso_stationary.cpp b/src/USER-SPH/fix_meso_stationary.cpp index 9a08d28fd9..793e8dd217 100644 --- a/src/USER-SPH/fix_meso_stationary.cpp +++ b/src/USER-SPH/fix_meso_stationary.cpp @@ -38,11 +38,11 @@ FixMesoStationary::FixMesoStationary(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if ((atom->e_flag != 1) || (atom->rho_flag != 1)) - error->all( + error->all(FLERR, "fix meso/stationary command requires atom_style with both energy and density, e.g. meso"); if (narg != 3) - error->all("Illegal number of arguments for fix meso/stationary command"); + error->all(FLERR,"Illegal number of arguments for fix meso/stationary command"); time_integrate = 0; } diff --git a/src/USER-SPH/pair_sph_heatconduction.cpp b/src/USER-SPH/pair_sph_heatconduction.cpp index e4af6f7663..2eacb71cf2 100644 --- a/src/USER-SPH/pair_sph_heatconduction.cpp +++ b/src/USER-SPH/pair_sph_heatconduction.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHHeatConduction::PairSPHHeatConduction(LAMMPS *lmp) : @@ -159,7 +156,7 @@ void PairSPHHeatConduction::allocate() { void PairSPHHeatConduction::settings(int narg, char **arg) { if (narg != 0) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/heatconduction"); } @@ -169,7 +166,7 @@ void PairSPHHeatConduction::settings(int narg, char **arg) { void PairSPHHeatConduction::coeff(int narg, char **arg) { if (narg != 4) - error->all("Incorrect number of args for pair_style sph/heatconduction coefficients"); + error->all(FLERR,"Incorrect number of args for pair_style sph/heatconduction coefficients"); if (!allocated) allocate(); @@ -192,7 +189,7 @@ void PairSPHHeatConduction::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -202,7 +199,7 @@ void PairSPHHeatConduction::coeff(int narg, char **arg) { double PairSPHHeatConduction::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("All pair sph/heatconduction coeffs are not set"); + error->all(FLERR,"All pair sph/heatconduction coeffs are not set"); } cut[j][i] = cut[i][j]; diff --git a/src/USER-SPH/pair_sph_idealgas.cpp b/src/USER-SPH/pair_sph_idealgas.cpp index 35baf218cb..a477ed0602 100644 --- a/src/USER-SPH/pair_sph_idealgas.cpp +++ b/src/USER-SPH/pair_sph_idealgas.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHIdealGas::PairSPHIdealGas(LAMMPS *lmp) : @@ -201,7 +198,7 @@ void PairSPHIdealGas::allocate() { void PairSPHIdealGas::settings(int narg, char **arg) { if (narg != 0) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/idealgas"); } @@ -211,7 +208,7 @@ void PairSPHIdealGas::settings(int narg, char **arg) { void PairSPHIdealGas::coeff(int narg, char **arg) { if (narg != 4) - error->all("Incorrect number of args for pair_style sph/idealgas coefficients"); + error->all(FLERR,"Incorrect number of args for pair_style sph/idealgas coefficients"); if (!allocated) allocate(); @@ -234,7 +231,7 @@ void PairSPHIdealGas::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair sph/idealgas coefficients"); + error->all(FLERR,"Incorrect args for pair sph/idealgas coefficients"); } /* ---------------------------------------------------------------------- @@ -244,7 +241,7 @@ void PairSPHIdealGas::coeff(int narg, char **arg) { double PairSPHIdealGas::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("All pair sph/idealgas coeffs are not set"); + error->all(FLERR,"All pair sph/idealgas coeffs are not set"); } cut[j][i] = cut[i][j]; diff --git a/src/USER-SPH/pair_sph_lj.cpp b/src/USER-SPH/pair_sph_lj.cpp index fd92cddc8f..4d73ef03f8 100644 --- a/src/USER-SPH/pair_sph_lj.cpp +++ b/src/USER-SPH/pair_sph_lj.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHLJ::PairSPHLJ(LAMMPS *lmp) : @@ -208,7 +205,7 @@ void PairSPHLJ::allocate() { void PairSPHLJ::settings(int narg, char **arg) { if (narg != 0) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/lj"); } @@ -218,7 +215,7 @@ void PairSPHLJ::settings(int narg, char **arg) { void PairSPHLJ::coeff(int narg, char **arg) { if (narg != 4) - error->all( + error->all(FLERR, "Incorrect args for pair_style sph/lj coefficients"); if (!allocated) allocate(); @@ -242,7 +239,7 @@ void PairSPHLJ::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -252,7 +249,7 @@ void PairSPHLJ::coeff(int narg, char **arg) { double PairSPHLJ::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("All pair sph/lj coeffs are not set"); + error->all(FLERR,"All pair sph/lj coeffs are not set"); } cut[j][i] = cut[i][j]; diff --git a/src/USER-SPH/pair_sph_rhosum.cpp b/src/USER-SPH/pair_sph_rhosum.cpp index b846b1bb49..f022e6dc40 100644 --- a/src/USER-SPH/pair_sph_rhosum.cpp +++ b/src/USER-SPH/pair_sph_rhosum.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHRhoSum::PairSPHRhoSum(LAMMPS *lmp) : @@ -229,7 +226,7 @@ void PairSPHRhoSum::allocate() { void PairSPHRhoSum::settings(int narg, char **arg) { if (narg != 1) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/rhosum"); nstep = force->inumeric(arg[0]); } @@ -240,7 +237,7 @@ void PairSPHRhoSum::settings(int narg, char **arg) { void PairSPHRhoSum::coeff(int narg, char **arg) { if (narg != 3) - error->all("Incorrect number of args for sph/rhosum coefficients"); + error->all(FLERR,"Incorrect number of args for sph/rhosum coefficients"); if (!allocated) allocate(); @@ -261,7 +258,7 @@ void PairSPHRhoSum::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -270,7 +267,7 @@ void PairSPHRhoSum::coeff(int narg, char **arg) { double PairSPHRhoSum::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("All pair sph/rhosum coeffs are not set"); + error->all(FLERR,"All pair sph/rhosum coeffs are not set"); } cut[j][i] = cut[i][j]; diff --git a/src/USER-SPH/pair_sph_taitwater.cpp b/src/USER-SPH/pair_sph_taitwater.cpp index 0226d8fed4..86723dd4c8 100644 --- a/src/USER-SPH/pair_sph_taitwater.cpp +++ b/src/USER-SPH/pair_sph_taitwater.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHTaitwater::PairSPHTaitwater(LAMMPS *lmp) : @@ -229,7 +226,7 @@ void PairSPHTaitwater::allocate() { void PairSPHTaitwater::settings(int narg, char **arg) { if (narg != 0) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/taitwater"); } @@ -239,7 +236,7 @@ void PairSPHTaitwater::settings(int narg, char **arg) { void PairSPHTaitwater::coeff(int narg, char **arg) { if (narg != 6) - error->all( + error->all(FLERR, "Incorrect args for pair_style sph/taitwater coefficients"); if (!allocated) allocate(); @@ -274,7 +271,7 @@ void PairSPHTaitwater::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -284,7 +281,7 @@ void PairSPHTaitwater::coeff(int narg, char **arg) { double PairSPHTaitwater::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("Not all pair sph/taitwater coeffs are set"); + error->all(FLERR,"Not all pair sph/taitwater coeffs are set"); } cut[j][i] = cut[i][j]; diff --git a/src/USER-SPH/pair_sph_taitwater_morris.cpp b/src/USER-SPH/pair_sph_taitwater_morris.cpp index 5e5eb1d098..d1092cf6e1 100644 --- a/src/USER-SPH/pair_sph_taitwater_morris.cpp +++ b/src/USER-SPH/pair_sph_taitwater_morris.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSPHTaitwaterMorris::PairSPHTaitwaterMorris(LAMMPS *lmp) : @@ -230,7 +227,7 @@ void PairSPHTaitwaterMorris::allocate() { void PairSPHTaitwaterMorris::settings(int narg, char **arg) { if (narg != 0) - error->all( + error->all(FLERR, "Illegal number of setting arguments for pair_style sph/taitwater/morris"); } @@ -240,7 +237,7 @@ void PairSPHTaitwaterMorris::settings(int narg, char **arg) { void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { if (narg != 6) - error->all( + error->all(FLERR, "Incorrect args for pair_style sph/taitwater/morris coefficients"); if (!allocated) allocate(); @@ -271,7 +268,7 @@ void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { } if (count == 0) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -281,7 +278,7 @@ void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { double PairSPHTaitwaterMorris::init_one(int i, int j) { if (setflag[i][j] == 0) { - error->all("Not all pair sph/taitwater/morris coeffs are not set"); + error->all(FLERR,"Not all pair sph/taitwater/morris coeffs are not set"); } cut[j][i] = cut[i][j]; diff --git a/src/XTC/dump_xtc.cpp b/src/XTC/dump_xtc.cpp index f5355cdf5f..12d3719dad 100644 --- a/src/XTC/dump_xtc.cpp +++ b/src/XTC/dump_xtc.cpp @@ -54,9 +54,9 @@ int xdr3dfcoord(XDR *, float *, int *, float *); DumpXTC::DumpXTC(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg != 5) error->all("Illegal dump xtc command"); + if (narg != 5) error->all(FLERR,"Illegal dump xtc command"); if (binary || compressed || multifile || multiproc) - error->all("Invalid dump xtc filename"); + error->all(FLERR,"Invalid dump xtc filename"); size_one = 3; sort_flag = 1; @@ -70,7 +70,7 @@ DumpXTC::DumpXTC(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) bigint n = group->count(igroup); if (n > MAXSMALLINT/3/sizeof(float)) - error->all("Too many atoms for dump xtc"); + error->all(FLERR,"Too many atoms for dump xtc"); natoms = static_cast (n); memory->create(coords,3*natoms,"dump:coords"); @@ -103,11 +103,11 @@ DumpXTC::~DumpXTC() void DumpXTC::init_style() { if (sort_flag == 0 || sortcol != 0) - error->all("Dump xtc requires sorting by atom ID"); + error->all(FLERR,"Dump xtc requires sorting by atom ID"); // check that flush_flag is not set since dump::write() will use it - if (flush_flag) error->all("Cannot set dump_modify flush for dump xtc"); + if (flush_flag) error->all(FLERR,"Cannot set dump_modify flush for dump xtc"); // check that dump frequency has not changed and is not a variable @@ -115,11 +115,11 @@ void DumpXTC::init_style() for (idump = 0; idump < output->ndump; idump++) if (strcmp(id,output->dump[idump]->id) == 0) break; if (output->every_dump[idump] == 0) - error->all("Cannot use variable every setting for dump xtc"); + error->all(FLERR,"Cannot use variable every setting for dump xtc"); if (nevery_save == 0) nevery_save = output->every_dump[idump]; else if (nevery_save != output->every_dump[idump]) - error->all("Cannot change dump_modify every for dump xtc"); + error->all(FLERR,"Cannot change dump_modify every for dump xtc"); } /* ---------------------------------------------------------------------- */ @@ -131,17 +131,17 @@ void DumpXTC::openfile() fp = NULL; if (me == 0) - if (xdropen(&xd,filename,"w") == 0) error->one("Cannot open dump file"); + if (xdropen(&xd,filename,"w") == 0) error->one(FLERR,"Cannot open dump file"); } /* ---------------------------------------------------------------------- */ void DumpXTC::write_header(bigint nbig) { - if (nbig > MAXSMALLINT) error->all("Too many atoms for dump xtc"); + if (nbig > MAXSMALLINT) error->all(FLERR,"Too many atoms for dump xtc"); int n = nbig; if (update->ntimestep > MAXSMALLINT) - error->all("Too big a timestep for dump xtc"); + error->all(FLERR,"Too big a timestep for dump xtc"); int ntimestep = update->ntimestep; // all procs realloc coords if total count grew @@ -281,19 +281,19 @@ void DumpXTC::write_data(int n, double *mybuf) int DumpXTC::modify_param(int narg, char **arg) { if (strcmp(arg[0],"unwrap") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"yes") == 0) unwrap_flag = 1; else if (strcmp(arg[1],"no") == 0) unwrap_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); return 2; } else if (strcmp(arg[0],"precision") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); precision = atof(arg[1]); if ((fabs(precision-10.0) > EPS) && (fabs(precision-100.0) > EPS) && (fabs(precision-1000.0) > EPS) && (fabs(precision-10000.0) > EPS) && (fabs(precision-100000.0) > EPS) && (fabs(precision-1000000.0) > EPS)) - error->all("Illegal dump_modify command"); + error->all(FLERR,"Illegal dump_modify command"); return 2; } return 0; diff --git a/src/angle.cpp b/src/angle.cpp index 0073044d3c..fbed9116a9 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -49,9 +49,9 @@ Angle::~Angle() void Angle::init() { - if (!allocated) error->all("Angle coeffs are not set"); + if (!allocated) error->all(FLERR,"Angle coeffs are not set"); for (int i = 1; i <= atom->nangletypes; i++) - if (setflag[i] == 0) error->all("All angle coeffs are not set"); + if (setflag[i] == 0) error->all(FLERR,"All angle coeffs are not set"); } /* ---------------------------------------------------------------------- diff --git a/src/atom.cpp b/src/atom.cpp index a0f65365e6..f42b1250f1 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -42,9 +42,6 @@ using namespace LAMMPS_NS; #define EPSILON 1.0e-6 #define CUDA_CHUNK 3000 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) @@ -322,7 +319,7 @@ AtomVec *Atom::new_avec(const char *style, int narg, char **arg, #include "style_atom.h" #undef ATOM_CLASS - else error->all("Invalid atom style"); + else error->all(FLERR,"Invalid atom style"); return NULL; } @@ -348,7 +345,7 @@ void Atom::init() if (firstgroupname) { firstgroup = group->find(firstgroupname); if (firstgroup < 0) - error->all("Could not find atom_modify first group ID"); + error->all(FLERR,"Could not find atom_modify first group ID"); } else firstgroup = -1; // init AtomVec @@ -391,20 +388,20 @@ AtomVec *Atom::style_match(const char *style) void Atom::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal atom_modify command"); + if (narg == 0) error->all(FLERR,"Illegal atom_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"map") == 0) { - if (iarg+2 > narg) error->all("Illegal atom_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command"); if (strcmp(arg[iarg+1],"array") == 0) map_style = 1; else if (strcmp(arg[iarg+1],"hash") == 0) map_style = 2; - else error->all("Illegal atom_modify command"); + else error->all(FLERR,"Illegal atom_modify command"); if (domain->box_exist) - error->all("Atom_modify map command after simulation box is defined"); + error->all(FLERR,"Atom_modify map command after simulation box is defined"); iarg += 2; } else if (strcmp(arg[iarg],"first") == 0) { - if (iarg+2 > narg) error->all("Illegal atom_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command"); if (strcmp(arg[iarg+1],"all") == 0) { delete [] firstgroupname; firstgroupname = NULL; @@ -416,16 +413,16 @@ void Atom::modify_params(int narg, char **arg) } iarg += 2; } else if (strcmp(arg[iarg],"sort") == 0) { - if (iarg+3 > narg) error->all("Illegal atom_modify command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal atom_modify command"); sortfreq = atoi(arg[iarg+1]); userbinsize = atof(arg[iarg+2]); if (sortfreq < 0 || userbinsize < 0.0) - error->all("Illegal atom_modify command"); + error->all(FLERR,"Illegal atom_modify command"); if (sortfreq >= 0 && firstgroupname) - error->all("Atom_modify sort and first options " + error->all(FLERR,"Atom_modify sort and first options " "cannot be used together"); iarg += 3; - } else error->all("Illegal atom_modify command"); + } else error->all(FLERR,"Illegal atom_modify command"); } } @@ -446,7 +443,7 @@ void Atom::map_init() map_delete(); if (tag_enable == 0) - error->all("Cannot create an atom map unless atoms have IDs"); + error->all(FLERR,"Cannot create an atom map unless atoms have IDs"); int max = 0; for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]); @@ -764,7 +761,7 @@ void Atom::data_atoms(int n, char *buf) *next = '\n'; if (nwords != avec->size_data_atom && nwords != avec->size_data_atom + 3) - error->all("Incorrect atom format in data file"); + error->all(FLERR,"Incorrect atom format in data file"); char **values = new char*[nwords]; @@ -814,10 +811,10 @@ void Atom::data_atoms(int n, char *buf) next = strchr(buf,'\n'); values[0] = strtok(buf," \t\n\r\f"); - if (values[0] == NULL) error->all("Incorrect atom format in data file"); + if (values[0] == NULL) error->all(FLERR,"Incorrect atom format in data file"); for (m = 1; m < nwords; m++) { values[m] = strtok(NULL," \t\n\r\f"); - if (values[m] == NULL) error->all("Incorrect atom format in data file"); + if (values[m] == NULL) error->all(FLERR,"Incorrect atom format in data file"); } if (imageflag) @@ -863,7 +860,7 @@ void Atom::data_vels(int n, char *buf) *next = '\n'; if (nwords != avec->size_data_vel) - error->all("Incorrect velocity format in data file"); + error->all(FLERR,"Incorrect velocity format in data file"); char **values = new char*[nwords]; @@ -880,7 +877,7 @@ void Atom::data_vels(int n, char *buf) tagdata = atoi(values[0]); if (tagdata <= 0 || tagdata > map_tag_max) - error->one("Invalid atom ID in Velocities section of data file"); + error->one(FLERR,"Invalid atom ID in Velocities section of data file"); if ((m = map(tagdata)) >= 0) avec->data_vel(m,&values[1]); buf = next + 1; @@ -906,7 +903,7 @@ void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus) *next = '\n'; if (nwords != avec_bonus->size_data_bonus) - error->all("Incorrect bonus data format in data file"); + error->all(FLERR,"Incorrect bonus data format in data file"); char **values = new char*[nwords]; @@ -923,7 +920,7 @@ void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus) tagdata = atoi(values[0]); if (tagdata <= 0 || tagdata > map_tag_max) - error->one("Invalid atom ID in Bonus section of data file"); + error->one(FLERR,"Invalid atom ID in Bonus section of data file"); // ok to call child's data_atom_bonus() method thru parent avec_bonus, // since data_bonus() was called with child ptr, and method is virtual @@ -952,9 +949,9 @@ void Atom::data_bonds(int n, char *buf) sscanf(buf,"%d %d %d %d",&tmp,&itype,&atom1,&atom2); if (atom1 <= 0 || atom1 > map_tag_max || atom2 <= 0 || atom2 > map_tag_max) - error->one("Invalid atom ID in Bonds section of data file"); + error->one(FLERR,"Invalid atom ID in Bonds section of data file"); if (itype <= 0 || itype > nbondtypes) - error->one("Invalid bond type in Bonds section of data file"); + error->one(FLERR,"Invalid bond type in Bonds section of data file"); if ((m = map(atom1)) >= 0) { bond_type[m][num_bond[m]] = itype; bond_atom[m][num_bond[m]] = atom2; @@ -988,9 +985,9 @@ void Atom::data_angles(int n, char *buf) if (atom1 <= 0 || atom1 > map_tag_max || atom2 <= 0 || atom2 > map_tag_max || atom3 <= 0 || atom3 > map_tag_max) - error->one("Invalid atom ID in Angles section of data file"); + error->one(FLERR,"Invalid atom ID in Angles section of data file"); if (itype <= 0 || itype > nangletypes) - error->one("Invalid angle type in Angles section of data file"); + error->one(FLERR,"Invalid angle type in Angles section of data file"); if ((m = map(atom2)) >= 0) { angle_type[m][num_angle[m]] = itype; angle_atom1[m][num_angle[m]] = atom1; @@ -1036,9 +1033,9 @@ void Atom::data_dihedrals(int n, char *buf) atom2 <= 0 || atom2 > map_tag_max || atom3 <= 0 || atom3 > map_tag_max || atom4 <= 0 || atom4 > map_tag_max) - error->one("Invalid atom ID in Dihedrals section of data file"); + error->one(FLERR,"Invalid atom ID in Dihedrals section of data file"); if (itype <= 0 || itype > ndihedraltypes) - error->one("Invalid dihedral type in Dihedrals section of data file"); + error->one(FLERR,"Invalid dihedral type in Dihedrals section of data file"); if ((m = map(atom2)) >= 0) { dihedral_type[m][num_dihedral[m]] = itype; dihedral_atom1[m][num_dihedral[m]] = atom1; @@ -1095,9 +1092,9 @@ void Atom::data_impropers(int n, char *buf) atom2 <= 0 || atom2 > map_tag_max || atom3 <= 0 || atom3 > map_tag_max || atom4 <= 0 || atom4 > map_tag_max) - error->one("Invalid atom ID in Impropers section of data file"); + error->one(FLERR,"Invalid atom ID in Impropers section of data file"); if (itype <= 0 || itype > nimpropertypes) - error->one("Invalid improper type in Impropers section of data file"); + error->one(FLERR,"Invalid improper type in Impropers section of data file"); if ((m = map(atom2)) >= 0) { improper_type[m][num_improper[m]] = itype; improper_atom1[m][num_improper[m]] = atom1; @@ -1157,19 +1154,19 @@ void Atom::allocate_type_arrays() void Atom::set_mass(const char *str) { - if (mass == NULL) error->all("Cannot set mass for this atom style"); + if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style"); int itype; double mass_one; int n = sscanf(str,"%d %lg",&itype,&mass_one); - if (n != 2) error->all("Invalid mass line in data file"); + if (n != 2) error->all(FLERR,"Invalid mass line in data file"); - if (itype < 1 || itype > ntypes) error->all("Invalid type for mass set"); + if (itype < 1 || itype > ntypes) error->all(FLERR,"Invalid type for mass set"); mass[itype] = mass_one; mass_setflag[itype] = 1; - if (mass[itype] <= 0.0) error->all("Invalid mass value"); + if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value"); } /* ---------------------------------------------------------------------- @@ -1179,13 +1176,13 @@ void Atom::set_mass(const char *str) void Atom::set_mass(int itype, double value) { - if (mass == NULL) error->all("Cannot set mass for this atom style"); - if (itype < 1 || itype > ntypes) error->all("Invalid type for mass set"); + if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style"); + if (itype < 1 || itype > ntypes) error->all(FLERR,"Invalid type for mass set"); mass[itype] = value; mass_setflag[itype] = 1; - if (mass[itype] <= 0.0) error->all("Invalid mass value"); + if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value"); } /* ---------------------------------------------------------------------- @@ -1195,17 +1192,17 @@ void Atom::set_mass(int itype, double value) void Atom::set_mass(int narg, char **arg) { - if (mass == NULL) error->all("Cannot set mass for this atom style"); + if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style"); int lo,hi; force->bounds(arg[0],ntypes,lo,hi); - if (lo < 1 || hi > ntypes) error->all("Invalid type for mass set"); + if (lo < 1 || hi > ntypes) error->all(FLERR,"Invalid type for mass set"); for (int itype = lo; itype <= hi; itype++) { mass[itype] = atof(arg[1]); mass_setflag[itype] = 1; - if (mass[itype] <= 0.0) error->all("Invalid mass value"); + if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value"); } } @@ -1229,7 +1226,7 @@ void Atom::check_mass() { if (mass == NULL) return; for (int itype = 1; itype <= ntypes; itype++) - if (mass_setflag[itype] == 0) error->all("All masses are not set"); + if (mass_setflag[itype] == 0) error->all(FLERR,"All masses are not set"); } /* ---------------------------------------------------------------------- @@ -1433,7 +1430,7 @@ void Atom::sort() // if (current[i] != permute[i]) flag = 1; //int flagall; //MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - //if (flagall) error->all("Atom sort did not operate correctly"); + //if (flagall) error->all(FLERR,"Atom sort did not operate correctly"); } /* ---------------------------------------------------------------------- @@ -1463,7 +1460,7 @@ void Atom::setup_sort_bins() binsize = pow(1.0*CUDA_CHUNK/natoms*area,1.0/2.0); } } - if (binsize == 0.0) error->all("Atom sorting has bin size = 0.0"); + if (binsize == 0.0) error->all(FLERR,"Atom sorting has bin size = 0.0"); double bininv = 1.0/binsize; @@ -1495,7 +1492,7 @@ void Atom::setup_sort_bins() bininvz = nbinz / (bboxhi[2]-bboxlo[2]); if (1.0*nbinx*nbiny*nbinz > INT_MAX) - error->one("Too many atom sorting bins"); + error->one(FLERR,"Too many atom sorting bins"); nbins = nbinx*nbiny*nbinz; diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp index a0bf79a127..e4e2dcf5ee 100644 --- a/src/atom_vec_atomic.cpp +++ b/src/atom_vec_atomic.cpp @@ -56,7 +56,7 @@ void AtomVecAtomic::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -596,11 +596,11 @@ void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp index 5def3bd99f..81fc7a8ef8 100644 --- a/src/atom_vec_charge.cpp +++ b/src/atom_vec_charge.cpp @@ -58,7 +58,7 @@ void AtomVecCharge::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -647,11 +647,11 @@ void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[2]); diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index 2ccb91a6ca..d0cf4ce112 100755 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -78,7 +78,7 @@ void AtomVecEllipsoid::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -118,7 +118,7 @@ void AtomVecEllipsoid::grow_bonus() { nmax_bonus += DELTA_BONUS; if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), "atom:bonus"); @@ -1121,20 +1121,20 @@ void AtomVecEllipsoid::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); ellipsoid[nlocal] = atoi(values[2]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else if (ellipsoid[nlocal] == 1) ellipsoid[nlocal] = 0; - else error->one("Invalid atom type in Atoms section of data file"); + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[3]); if (rmass[nlocal] <= 0.0) - error->one("Invalid density in Atoms section of data file"); + error->one(FLERR,"Invalid density in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; @@ -1163,11 +1163,11 @@ int AtomVecEllipsoid::data_atom_hybrid(int nlocal, char **values) ellipsoid[nlocal] = atoi(values[0]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else if (ellipsoid[nlocal] == 1) ellipsoid[nlocal] = 0; - else error->one("Invalid atom type in Atoms section of data file"); + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[1]); if (rmass[nlocal] <= 0.0) - error->one("Invalid density in Atoms section of data file"); + error->one(FLERR,"Invalid density in Atoms section of data file"); return 2; } @@ -1179,7 +1179,7 @@ int AtomVecEllipsoid::data_atom_hybrid(int nlocal, char **values) void AtomVecEllipsoid::data_atom_bonus(int m, char **values) { if (ellipsoid[m]) - error->one("Assigning ellipsoid parameters to non-ellipsoid atom"); + error->one(FLERR,"Assigning ellipsoid parameters to non-ellipsoid atom"); if (nlocal_bonus == nmax_bonus) grow_bonus(); @@ -1188,7 +1188,7 @@ void AtomVecEllipsoid::data_atom_bonus(int m, char **values) shape[1] = 0.5 * atof(values[1]); shape[2] = 0.5 * atof(values[2]); if (shape[0] <= 0.0 || shape[1] <= 0.0 || shape[2] <= 0.0) - error->one("Invalid shape in Ellipsoids section of data file"); + error->one(FLERR,"Invalid shape in Ellipsoids section of data file"); double *quat = bonus[nlocal_bonus].quat; quat[0] = atof(values[3]); diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp index 03c0c501ea..b6b1dabdea 100644 --- a/src/atom_vec_hybrid.cpp +++ b/src/atom_vec_hybrid.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELTA 10000 /* ---------------------------------------------------------------------- */ @@ -36,7 +33,7 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) : { int i,k,dummy; - if (narg < 1) error->all("Illegal atom_style command"); + if (narg < 1) error->all(FLERR,"Illegal atom_style command"); // create sub-styles @@ -47,9 +44,9 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) : for (i = 0; i < narg; i++) { for (k = 0; k < i; k++) if (strcmp(arg[i],keywords[k]) == 0) - error->all("Atom style hybrid cannot use same atom style twice"); + error->all(FLERR,"Atom style hybrid cannot use same atom style twice"); if (strcmp(arg[i],"hybrid") == 0) - error->all("Atom style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Atom style hybrid cannot have hybrid as an argument"); styles[i] = atom->new_avec(arg[i],0,NULL,NULL,dummy); keywords[i] = new char[strlen(arg[i])+1]; strcpy(keywords[i],arg[i]); @@ -121,7 +118,7 @@ void AtomVecHybrid::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); // sub-styles perform all reallocation // turn off nextra_grow so hybrid can do that once below @@ -814,11 +811,11 @@ void AtomVecHybrid::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index b17817412e..babc914387 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -89,7 +89,7 @@ void AtomVecSphere::grow(int n) else nmax = n; atom->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) - error->one("Per-processor system is too big"); + error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); @@ -949,19 +949,19 @@ void AtomVecSphere::data_atom(double *coord, int imagetmp, char **values) tag[nlocal] = atoi(values[0]); if (tag[nlocal] <= 0) - error->one("Invalid atom ID in Atoms section of data file"); + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one("Invalid atom type in Atoms section of data file"); + error->one(FLERR,"Invalid atom type in Atoms section of data file"); radius[nlocal] = 0.5 * atof(values[2]); if (radius[nlocal] < 0.0) - error->one("Invalid radius in Atoms section of data file"); + error->one(FLERR,"Invalid radius in Atoms section of data file"); double density = atof(values[3]); if (density <= 0.0) - error->one("Invalid density in Atoms section of data file"); + error->one(FLERR,"Invalid density in Atoms section of data file"); if (radius[nlocal] == 0.0) rmass[nlocal] = density; else @@ -994,11 +994,11 @@ int AtomVecSphere::data_atom_hybrid(int nlocal, char **values) { radius[nlocal] = 0.5 * atof(values[0]); if (radius[nlocal] < 0.0) - error->one("Invalid radius in Atoms section of data file"); + error->one(FLERR,"Invalid radius in Atoms section of data file"); double density = atof(values[1]); if (density <= 0.0) - error->one("Invalid density in Atoms section of data file"); + error->one(FLERR,"Invalid density in Atoms section of data file"); if (radius[nlocal] == 0.0) rmass[nlocal] = density; else diff --git a/src/bond.cpp b/src/bond.cpp index b4365acf36..92310df653 100644 --- a/src/bond.cpp +++ b/src/bond.cpp @@ -50,9 +50,9 @@ Bond::~Bond() void Bond::init() { - if (!allocated) error->all("Bond coeffs are not set"); + if (!allocated) error->all(FLERR,"Bond coeffs are not set"); for (int i = 1; i <= atom->nbondtypes; i++) - if (setflag[i] == 0) error->all("All bond coeffs are not set"); + if (setflag[i] == 0) error->all(FLERR,"All bond coeffs are not set"); init_style(); } diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp index c06aa5647b..435685d5ec 100644 --- a/src/bond_hybrid.cpp +++ b/src/bond_hybrid.cpp @@ -161,7 +161,7 @@ void BondHybrid::settings(int narg, char **arg) { int i,m,istyle; - if (narg < 1) error->all("Illegal bond_style command"); + if (narg < 1) error->all(FLERR,"Illegal bond_style command"); // delete old lists, since cannot just change settings @@ -211,11 +211,11 @@ void BondHybrid::settings(int narg, char **arg) while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) - error->all("Bond style hybrid cannot use same pair style twice"); + error->all(FLERR,"Bond style hybrid cannot use same pair style twice"); if (strcmp(arg[i],"hybrid") == 0) - error->all("Bond style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Bond style hybrid cannot have hybrid as an argument"); if (strcmp(arg[i],"none") == 0) - error->all("Bond style hybrid cannot have none as an argument"); + error->all(FLERR,"Bond style hybrid cannot have none as an argument"); styles[nstyles] = force->new_bond(arg[i]); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); @@ -249,7 +249,7 @@ void BondHybrid::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[1],"none") == 0) none = 1; - else error->all("Bond coeff for hybrid has invalid style"); + else error->all(FLERR,"Bond coeff for hybrid has invalid style"); } // move 1st arg to 2nd arg @@ -285,7 +285,7 @@ void BondHybrid::init_style() double BondHybrid::equilibrium_distance(int i) { - if (map[i] < 0) error->one("Invoked bond equil distance on bond style none"); + if (map[i] < 0) error->one(FLERR,"Invoked bond equil distance on bond style none"); return styles[map[i]]->equilibrium_distance(i); } @@ -334,7 +334,7 @@ void BondHybrid::read_restart(FILE *fp) double BondHybrid::single(int type, double rsq, int i, int j) { - if (map[type] < 0) error->one("Invoked bond single on bond style none"); + if (map[type] < 0) error->one(FLERR,"Invoked bond single on bond style none"); return styles[map[type]]->single(type,rsq,i,j); } diff --git a/src/change_box.cpp b/src/change_box.cpp index 2bb5ad45fe..34f2f67b0b 100644 --- a/src/change_box.cpp +++ b/src/change_box.cpp @@ -32,27 +32,27 @@ ChangeBox::ChangeBox(LAMMPS *lmp) : Pointers(lmp) {} void ChangeBox::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Change_box command before simulation box is defined"); - if (narg != 1) error->all("Illegal change_box command"); + error->all(FLERR,"Change_box command before simulation box is defined"); + if (narg != 1) error->all(FLERR,"Illegal change_box command"); int style; if (strcmp(arg[0],"ortho") == 0) style = ORTHO; else if (strcmp(arg[0],"triclinic") == 0) style = TRICLINIC; - else error->all("Illegal change_box command"); + else error->all(FLERR,"Illegal change_box command"); if (style == ORTHO && domain->triclinic == 0) - error->all("Change_box operation is invalid"); + error->all(FLERR,"Change_box operation is invalid"); if (style == TRICLINIC && domain->triclinic == 1) - error->all("Change_box operation is invalid"); + error->all(FLERR,"Change_box operation is invalid"); if (style == ORTHO && (domain->xy != 0.0 || domain->yz != 0.0 || domain->xz != 0.0)) - error->all("Cannot change box to orthogonal when tilt is non-zero"); + error->all(FLERR,"Cannot change box to orthogonal when tilt is non-zero"); if (output->ndump) - error->all("Cannot change box with dumps defined"); + error->all(FLERR,"Cannot change box with dumps defined"); for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->no_change_box) - error->all("Cannot change box with certain fixes defined"); + error->all(FLERR,"Cannot change box with certain fixes defined"); if (style == ORTHO) domain->triclinic = 0; else domain->triclinic = 1; diff --git a/src/comm.cpp b/src/comm.cpp index b5008dc3af..e28baab37f 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -46,9 +46,6 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 #define BUFMIN 1000 #define BUFEXTRA 1000 - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define BIG 1.0e20 enum{SINGLE,MULTI}; @@ -138,9 +135,9 @@ void Comm::set_procs() procs2box(); if (procgrid[0]*procgrid[1]*procgrid[2] != nprocs) - error->all("Bad grid of processors"); + error->all(FLERR,"Bad grid of processors"); if (domain->dimension == 2 && procgrid[2] != 1) - error->all("Processor count in z must be 1 for 2d simulation"); + error->all(FLERR,"Processor count in z must be 1 for 2d simulation"); if (grid2proc) memory->destroy(grid2proc); memory->create(grid2proc,procgrid[0],procgrid[1],procgrid[2], @@ -1341,36 +1338,36 @@ void Comm::free_multi() void Comm::set(int narg, char **arg) { - if (narg < 1) error->all("Illegal communicate command"); + if (narg < 1) error->all(FLERR,"Illegal communicate command"); if (strcmp(arg[0],"single") == 0) style = SINGLE; else if (strcmp(arg[0],"multi") == 0) style = MULTI; - else error->all("Illegal communicate command"); + else error->all(FLERR,"Illegal communicate command"); int iarg = 1; while (iarg < narg) { if (strcmp(arg[iarg],"group") == 0) { - if (iarg+2 > narg) error->all("Illegal communicate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command"); bordergroup = group->find(arg[iarg+1]); if (bordergroup < 0) - error->all("Invalid group in communicate command"); + error->all(FLERR,"Invalid group in communicate command"); if (bordergroup && (atom->firstgroupname == NULL || strcmp(arg[iarg+1],atom->firstgroupname) != 0)) - error->all("Communicate group != atom_modify first group"); + error->all(FLERR,"Communicate group != atom_modify first group"); iarg += 2; } else if (strcmp(arg[iarg],"cutoff") == 0) { - if (iarg+2 > narg) error->all("Illegal communicate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command"); cutghostuser = atof(arg[iarg+1]); if (cutghostuser < 0.0) - error->all("Invalid cutoff in communicate command"); + error->all(FLERR,"Invalid cutoff in communicate command"); iarg += 2; } else if (strcmp(arg[iarg],"vel") == 0) { - if (iarg+2 > narg) error->all("Illegal communicate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command"); if (strcmp(arg[iarg+1],"yes") == 0) ghost_velocity = 1; else if (strcmp(arg[iarg+1],"no") == 0) ghost_velocity = 0; - else error->all("Illegal communicate command"); + else error->all(FLERR,"Illegal communicate command"); iarg += 2; - } else error->all("Illegal communicate command"); + } else error->all(FLERR,"Illegal communicate command"); } } diff --git a/src/compute.cpp b/src/compute.cpp index 230c15919c..5b8dc93f2a 100644 --- a/src/compute.cpp +++ b/src/compute.cpp @@ -29,14 +29,11 @@ using namespace LAMMPS_NS; #define DELTA 4 #define BIG 2000000000 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) { - if (narg < 3) error->all("Illegal compute command"); + if (narg < 3) error->all(FLERR,"Illegal compute command"); // compute ID, group, and style // ID must be all alphanumeric chars or underscores @@ -47,10 +44,10 @@ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) for (int i = 0; i < n-1; i++) if (!isalnum(id[i]) && id[i] != '_') - error->all("Compute ID must be alphanumeric or underscore characters"); + error->all(FLERR,"Compute ID must be alphanumeric or underscore characters"); igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find compute group ID"); + if (igroup == -1) error->all(FLERR,"Could not find compute group ID"); groupbit = group->bitmask[igroup]; n = strlen(arg[2]) + 1; @@ -103,27 +100,27 @@ Compute::~Compute() void Compute::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal compute_modify command"); + if (narg == 0) error->all(FLERR,"Illegal compute_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"extra") == 0) { - if (iarg+2 > narg) error->all("Illegal compute_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute_modify command"); extra_dof = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"dynamic") == 0) { - if (iarg+2 > narg) error->all("Illegal compute_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute_modify command"); if (strcmp(arg[iarg+1],"no") == 0) dynamic = 0; else if (strcmp(arg[iarg+1],"yes") == 0) dynamic = 1; - else error->all("Illegal compute_modify command"); + else error->all(FLERR,"Illegal compute_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"thermo") == 0) { - if (iarg+2 > narg) error->all("Illegal compute_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute_modify command"); if (strcmp(arg[iarg+1],"no") == 0) thermoflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) thermoflag = 1; - else error->all("Illegal compute_modify command"); + else error->all(FLERR,"Illegal compute_modify command"); iarg += 2; - } else error->all("Illegal compute_modify command"); + } else error->all(FLERR,"Illegal compute_modify command"); } } @@ -140,7 +137,7 @@ void Compute::reset_extra_dof() void Compute::reset_extra_compute_fix(char *) { - error->all("Compute does not allow an extra compute or fix to be reset"); + error->all(FLERR,"Compute does not allow an extra compute or fix to be reset"); } /* ---------------------------------------------------------------------- @@ -238,7 +235,7 @@ int Compute::molecules_in_group(int &idlo, int &idhi) int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && comm->me == 0) - error->warning("Atom with molecule ID = 0 included in " + error->warning(FLERR,"Atom with molecule ID = 0 included in " "compute molecule group"); MPI_Allreduce(&lo,&idlo,1,MPI_INT,MPI_MIN,world); @@ -280,7 +277,7 @@ int Compute::molecules_in_group(int &idlo, int &idhi) MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && comm->me == 0) - error->warning("One or more compute molecules has atoms not in group"); + error->warning(FLERR,"One or more compute molecules has atoms not in group"); // if molmap simply stores 1 to Nmolecules, then free it diff --git a/src/compute_angle_local.cpp b/src/compute_angle_local.cpp index 6f9bce918c..a126348d31 100644 --- a/src/compute_angle_local.cpp +++ b/src/compute_angle_local.cpp @@ -32,10 +32,10 @@ using namespace LAMMPS_NS; ComputeAngleLocal::ComputeAngleLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute angle/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute angle/local command"); if (atom->avec->angles_allow == 0) - error->all("Compute angle/local used when angles are not allowed"); + error->all(FLERR,"Compute angle/local used when angles are not allowed"); local_flag = 1; nvalues = narg - 3; @@ -50,7 +50,7 @@ ComputeAngleLocal::ComputeAngleLocal(LAMMPS *lmp, int narg, char **arg) : i = iarg-3; if (strcmp(arg[iarg],"theta") == 0) tflag = nvalues++; else if (strcmp(arg[iarg],"eng") == 0) eflag = nvalues++; - else error->all("Invalid keyword in compute angle/local command"); + else error->all(FLERR,"Invalid keyword in compute angle/local command"); } nmax = 0; @@ -71,7 +71,7 @@ ComputeAngleLocal::~ComputeAngleLocal() void ComputeAngleLocal::init() { if (force->angle == NULL) - error->all("No angle style is defined for compute angle/local"); + error->all(FLERR,"No angle style is defined for compute angle/local"); // do initial memory allocation so that memory_usage() is correct diff --git a/src/compute_atom_molecule.cpp b/src/compute_atom_molecule.cpp index 9466ae92a9..2bb6f7a510 100644 --- a/src/compute_atom_molecule.cpp +++ b/src/compute_atom_molecule.cpp @@ -36,10 +36,10 @@ ComputeAtomMolecule:: ComputeAtomMolecule(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute atom/molecule command"); + if (narg < 4) error->all(FLERR,"Illegal compute atom/molecule command"); if (atom->molecular == 0) - error->all("Compute atom/molecule requires molecular atom style"); + error->all(FLERR,"Compute atom/molecule requires molecular atom style"); // parse args @@ -65,7 +65,7 @@ ComputeAtomMolecule(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal compute reduce command"); + error->all(FLERR,"Illegal compute reduce command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -75,7 +75,7 @@ ComputeAtomMolecule(LAMMPS *lmp, int narg, char **arg) : strcpy(ids[nvalues],suffix); nvalues++; delete [] suffix; - } else error->all("Illegal compute atom/molecule command"); + } else error->all(FLERR,"Illegal compute atom/molecule command"); iarg++; } @@ -86,46 +86,46 @@ ComputeAtomMolecule(LAMMPS *lmp, int narg, char **arg) : if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for compute atom/molecule does not exist"); + error->all(FLERR,"Compute ID for compute atom/molecule does not exist"); if (modify->compute[icompute]->peratom_flag == 0) - error->all("Compute atom/molecule compute does not " + error->all(FLERR,"Compute atom/molecule compute does not " "calculate per-atom values"); if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Compute atom/molecule compute does not " + error->all(FLERR,"Compute atom/molecule compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Compute atom/molecule compute does not " + error->all(FLERR,"Compute atom/molecule compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Compute atom/molecule compute array is " + error->all(FLERR,"Compute atom/molecule compute array is " "accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for compute atom/molecule does not exist"); + error->all(FLERR,"Fix ID for compute atom/molecule does not exist"); if (modify->fix[ifix]->peratom_flag) - error->all("Compute atom/molecule fix does not " + error->all(FLERR,"Compute atom/molecule fix does not " "calculate per-atom values"); if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Compute atom/molecule fix does not " + error->all(FLERR,"Compute atom/molecule fix does not " "calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Compute atom/molecule fix does not " + error->all(FLERR,"Compute atom/molecule fix does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Compute atom/molecule fix array is accessed out-of-range"); + error->all(FLERR,"Compute atom/molecule fix array is accessed out-of-range"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for compute atom/molecule does not exist"); + error->all(FLERR,"Variable name for compute atom/molecule does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all("Compute atom/molecule variable is not " + error->all(FLERR,"Compute atom/molecule variable is not " "atom-style variable"); } } @@ -179,7 +179,7 @@ void ComputeAtomMolecule::init() { int ntmp = molecules_in_group(idlo,idhi); if (ntmp != nmolecules) - error->all("Molecule count changed in compute atom/molecule"); + error->all(FLERR,"Molecule count changed in compute atom/molecule"); // set indices and check validity of all computes,fixes,variables @@ -187,19 +187,19 @@ void ComputeAtomMolecule::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for compute atom/molecule does not exist"); + error->all(FLERR,"Compute ID for compute atom/molecule does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for compute atom/molecule does not exist"); + error->all(FLERR,"Fix ID for compute atom/molecule does not exist"); value2index[m] = ifix; } else if (which[m] == VARIABLE) { int ivariable = input->variable->find(ids[m]); if (ivariable < 0) - error->all("Variable name for compute atom/molecule does not exist"); + error->all(FLERR,"Variable name for compute atom/molecule does not exist"); value2index[m] = ivariable; } else value2index[m] = -1; @@ -301,7 +301,7 @@ void ComputeAtomMolecule::compute_one(int m) } else if (which[m] == FIX) { if (update->ntimestep % modify->fix[vidx]->peratom_freq) - error->all("Fix used in compute atom/molecule not computed " + error->all(FLERR,"Fix used in compute atom/molecule not computed " "at compatible time"); Fix *fix = modify->fix[vidx]; diff --git a/src/compute_bond_local.cpp b/src/compute_bond_local.cpp index af1710520f..76feec4209 100644 --- a/src/compute_bond_local.cpp +++ b/src/compute_bond_local.cpp @@ -32,10 +32,10 @@ using namespace LAMMPS_NS; ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute bond/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute bond/local command"); if (atom->avec->bonds_allow == 0) - error->all("Compute bond/local used when bonds are not allowed"); + error->all(FLERR,"Compute bond/local used when bonds are not allowed"); local_flag = 1; nvalues = narg - 3; @@ -50,7 +50,7 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : i = iarg-3; if (strcmp(arg[iarg],"dist") == 0) dflag = nvalues++; else if (strcmp(arg[iarg],"eng") == 0) eflag = nvalues++; - else error->all("Invalid keyword in compute bond/local command"); + else error->all(FLERR,"Invalid keyword in compute bond/local command"); } nmax = 0; @@ -71,7 +71,7 @@ ComputeBondLocal::~ComputeBondLocal() void ComputeBondLocal::init() { if (force->bond == NULL) - error->all("No bond style is defined for compute bond/local"); + error->all(FLERR,"No bond style is defined for compute bond/local"); // do initial memory allocation so that memory_usage() is correct diff --git a/src/compute_centro_atom.cpp b/src/compute_centro_atom.cpp index c166e3c2f5..68478955c8 100644 --- a/src/compute_centro_atom.cpp +++ b/src/compute_centro_atom.cpp @@ -37,14 +37,14 @@ using namespace LAMMPS_NS; ComputeCentroAtom::ComputeCentroAtom(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(FLERR,"Illegal compute centro/atom command"); if (strcmp(arg[3],"fcc") == 0) nnn = 12; else if (strcmp(arg[3],"bcc") == 0) nnn = 8; else nnn = atoi(arg[3]); if (nnn <= 0 || nnn % 2) - error->all("Illegal neighbor value for compute centro/atom command"); + error->all(FLERR,"Illegal neighbor value for compute centro/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -70,13 +70,13 @@ ComputeCentroAtom::~ComputeCentroAtom() void ComputeCentroAtom::init() { if (force->pair == NULL) - error->all("Compute centro/atom requires a pair style be defined"); + error->all(FLERR,"Compute centro/atom requires a pair style be defined"); int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"centro/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute centro/atom"); + error->warning(FLERR,"More than one compute centro/atom"); // need an occasional full neighbor list diff --git a/src/compute_cluster_atom.cpp b/src/compute_cluster_atom.cpp index cb42cdbbf6..9b8036ad29 100644 --- a/src/compute_cluster_atom.cpp +++ b/src/compute_cluster_atom.cpp @@ -29,15 +29,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute cluster/atom command"); + if (narg != 4) error->all(FLERR,"Illegal compute cluster/atom command"); double cutoff = atof(arg[3]); cutsq = cutoff*cutoff; @@ -62,11 +59,11 @@ ComputeClusterAtom::~ComputeClusterAtom() void ComputeClusterAtom::init() { if (atom->tag_enable == 0) - error->all("Cannot use compute cluster/atom unless atoms have IDs"); + error->all(FLERR,"Cannot use compute cluster/atom unless atoms have IDs"); if (force->pair == NULL) - error->all("Compute cluster/atom requires a pair style be defined"); + error->all(FLERR,"Compute cluster/atom requires a pair style be defined"); if (sqrt(cutsq) > force->pair->cutforce) - error->all("Compute cluster/atom cutoff is longer than pairwise cutoff"); + error->all(FLERR,"Compute cluster/atom cutoff is longer than pairwise cutoff"); // need an occasional full neighbor list // full required so that pair of atoms on 2 procs both set their clusterID @@ -82,7 +79,7 @@ void ComputeClusterAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"cluster/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute cluster/atom"); + error->warning(FLERR,"More than one compute cluster/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_cna_atom.cpp b/src/compute_cna_atom.cpp index f07ffd6fc9..5df5b68919 100644 --- a/src/compute_cna_atom.cpp +++ b/src/compute_cna_atom.cpp @@ -33,9 +33,6 @@ using namespace LAMMPS_NS; -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAXNEAR 16 #define MAXCOMMON 8 @@ -47,13 +44,13 @@ enum{NCOMMON,NBOND,MAXBOND,MINBOND}; ComputeCNAAtom::ComputeCNAAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute cna/atom command"); + if (narg != 4) error->all(FLERR,"Illegal compute cna/atom command"); peratom_flag = 1; size_peratom_cols = 0; double cutoff = atof(arg[3]); - if (cutoff < 0.0) error->all("Illegal compute cna/atom command"); + if (cutoff < 0.0) error->all(FLERR,"Illegal compute cna/atom command"); cutsq = cutoff*cutoff; nmax = 0; @@ -76,22 +73,22 @@ ComputeCNAAtom::~ComputeCNAAtom() void ComputeCNAAtom::init() { if (force->pair == NULL) - error->all("Compute cna/atom requires a pair style be defined"); + error->all(FLERR,"Compute cna/atom requires a pair style be defined"); if (sqrt(cutsq) > force->pair->cutforce) - error->all("Compute cna/atom cutoff is longer than pairwise cutoff"); + error->all(FLERR,"Compute cna/atom cutoff is longer than pairwise cutoff"); // cannot use neighbor->cutneighmax b/c neighbor has not yet been init if (2.0*sqrt(cutsq) > force->pair->cutforce + neighbor->skin && comm->me == 0) - error->warning("Compute cna/atom cutoff may be too large to find " + error->warning(FLERR,"Compute cna/atom cutoff may be too large to find " "ghost atom neighbors"); int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"cna/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute cna/atom defined"); + error->warning(FLERR,"More than one compute cna/atom defined"); // need an occasional full neighbor list @@ -192,7 +189,7 @@ void ComputeCNAAtom::compute_peratom() if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many neighbors in CNA for %d atoms",nerrorall); - error->warning(str,0); + error->warning(FLERR,str,0); } // compute CNA for each atom in group @@ -353,7 +350,7 @@ void ComputeCNAAtom::compute_peratom() if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many common neighbors in CNA %d times",nerrorall); - error->warning(str); + error->warning(FLERR,str); } } diff --git a/src/compute_com.cpp b/src/compute_com.cpp index dba4d626bd..d0f4296c42 100644 --- a/src/compute_com.cpp +++ b/src/compute_com.cpp @@ -23,7 +23,7 @@ using namespace LAMMPS_NS; ComputeCOM::ComputeCOM(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute com command"); + if (narg != 3) error->all(FLERR,"Illegal compute com command"); vector_flag = 1; size_vector = 3; diff --git a/src/compute_com_molecule.cpp b/src/compute_com_molecule.cpp index 5218f415a0..ad3ba957bd 100644 --- a/src/compute_com_molecule.cpp +++ b/src/compute_com_molecule.cpp @@ -25,10 +25,10 @@ using namespace LAMMPS_NS; ComputeCOMMolecule::ComputeCOMMolecule(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute com/molecule command"); + if (narg != 3) error->all(FLERR,"Illegal compute com/molecule command"); if (atom->molecular == 0) - error->all("Compute com/molecule requires molecular atom style"); + error->all(FLERR,"Compute com/molecule requires molecular atom style"); array_flag = 1; size_array_cols = 3; @@ -88,7 +88,7 @@ void ComputeCOMMolecule::init() { int ntmp = molecules_in_group(idlo,idhi); if (ntmp != nmolecules) - error->all("Molecule count changed in compute com/molecule"); + error->all(FLERR,"Molecule count changed in compute com/molecule"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_coord_atom.cpp b/src/compute_coord_atom.cpp index 5f3c087b32..85fe47ec44 100644 --- a/src/compute_coord_atom.cpp +++ b/src/compute_coord_atom.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; ComputeCoordAtom::ComputeCoordAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute coord/atom command"); + if (narg != 4) error->all(FLERR,"Illegal compute coord/atom command"); double cutoff = atof(arg[3]); cutsq = cutoff*cutoff; @@ -58,9 +58,9 @@ ComputeCoordAtom::~ComputeCoordAtom() void ComputeCoordAtom::init() { if (force->pair == NULL) - error->all("Compute coord/atom requires a pair style be defined"); + error->all(FLERR,"Compute coord/atom requires a pair style be defined"); if (sqrt(cutsq) > force->pair->cutforce) - error->all("Compute coord/atom cutoff is longer than pairwise cutoff"); + error->all(FLERR,"Compute coord/atom cutoff is longer than pairwise cutoff"); // need an occasional full neighbor list @@ -75,7 +75,7 @@ void ComputeCoordAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"coord/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute coord/atom"); + error->warning(FLERR,"More than one compute coord/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_dihedral_local.cpp b/src/compute_dihedral_local.cpp index 361a0f9772..6215346717 100644 --- a/src/compute_dihedral_local.cpp +++ b/src/compute_dihedral_local.cpp @@ -26,20 +26,17 @@ using namespace LAMMPS_NS; #define DELTA 10000 - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) -#define SMALL 0.001 +#define SMALL 0.001 /* ---------------------------------------------------------------------- */ ComputeDihedralLocal::ComputeDihedralLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute dihedral/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute dihedral/local command"); if (atom->avec->dihedrals_allow == 0) - error->all("Compute dihedral/local used when dihedrals are not allowed"); + error->all(FLERR,"Compute dihedral/local used when dihedrals are not allowed"); local_flag = 1; nvalues = narg - 3; @@ -53,7 +50,7 @@ ComputeDihedralLocal::ComputeDihedralLocal(LAMMPS *lmp, int narg, char **arg) : for (int iarg = 3; iarg < narg; iarg++) { i = iarg-3; if (strcmp(arg[iarg],"phi") == 0) pflag = nvalues++; - else error->all("Invalid keyword in compute dihedral/local command"); + else error->all(FLERR,"Invalid keyword in compute dihedral/local command"); } nmax = 0; @@ -74,7 +71,7 @@ ComputeDihedralLocal::~ComputeDihedralLocal() void ComputeDihedralLocal::init() { if (force->dihedral == NULL) - error->all("No dihedral style is defined for compute dihedral/local"); + error->all(FLERR,"No dihedral style is defined for compute dihedral/local"); // do initial memory allocation so that memory_usage() is correct diff --git a/src/compute_displace_atom.cpp b/src/compute_displace_atom.cpp index fbd828be5d..59370ea831 100644 --- a/src/compute_displace_atom.cpp +++ b/src/compute_displace_atom.cpp @@ -30,7 +30,7 @@ using namespace LAMMPS_NS; ComputeDisplaceAtom::ComputeDisplaceAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute displace/atom command"); + if (narg != 3) error->all(FLERR,"Illegal compute displace/atom command"); peratom_flag = 1; size_peratom_cols = 4; @@ -77,7 +77,7 @@ void ComputeDisplaceAtom::init() // set fix which stores original atom coords int ifix = modify->find_fix(id_fix); - if (ifix < 0) error->all("Could not find compute displace/atom fix ID"); + if (ifix < 0) error->all(FLERR,"Could not find compute displace/atom fix ID"); fix = modify->fix[ifix]; } diff --git a/src/compute_erotate_sphere.cpp b/src/compute_erotate_sphere.cpp index 1aa5ad8d99..47bee40890 100644 --- a/src/compute_erotate_sphere.cpp +++ b/src/compute_erotate_sphere.cpp @@ -30,7 +30,7 @@ using namespace LAMMPS_NS; ComputeERotateSphere::ComputeERotateSphere(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute erotate/sphere command"); + if (narg != 3) error->all(FLERR,"Illegal compute erotate/sphere command"); scalar_flag = 1; extscalar = 1; @@ -38,7 +38,7 @@ ComputeERotateSphere::ComputeERotateSphere(LAMMPS *lmp, int narg, char **arg) : // error check if (!atom->sphere_flag) - error->all("Compute erotate/sphere requires atom style sphere"); + error->all(FLERR,"Compute erotate/sphere requires atom style sphere"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_group_group.cpp b/src/compute_group_group.cpp index ebbfe16d93..5393fae0be 100644 --- a/src/compute_group_group.cpp +++ b/src/compute_group_group.cpp @@ -35,7 +35,7 @@ using namespace LAMMPS_NS; ComputeGroupGroup::ComputeGroupGroup(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute group/group command"); + if (narg != 4) error->all(FLERR,"Illegal compute group/group command"); scalar_flag = vector_flag = 1; size_vector = 3; @@ -47,7 +47,7 @@ ComputeGroupGroup::ComputeGroupGroup(LAMMPS *lmp, int narg, char **arg) : strcpy(group2,arg[3]); jgroup = group->find(group2); - if (jgroup == -1) error->all("Compute group/group group ID does not exist"); + if (jgroup == -1) error->all(FLERR,"Compute group/group group ID does not exist"); jgroupbit = group->bitmask[jgroup]; vector = new double[3]; @@ -66,13 +66,13 @@ ComputeGroupGroup::~ComputeGroupGroup() void ComputeGroupGroup::init() { if (force->pair == NULL) - error->all("No pair style defined for compute group/group"); + error->all(FLERR,"No pair style defined for compute group/group"); // if non-hybrid, then error if single_enable = 0 // if hybrid, let hybrid determine if sub-style sets single_enable = 0 if (force->pair_match("hybrid",0) == NULL && force->pair->single_enable == 0) - error->all("Pair style does not support compute group/group"); + error->all(FLERR,"Pair style does not support compute group/group"); pair = force->pair; cutsq = force->pair->cutsq; @@ -80,7 +80,7 @@ void ComputeGroupGroup::init() // recheck that group 2 has not been deleted jgroup = group->find(group2); - if (jgroup == -1) error->all("Compute group/group group ID does not exist"); + if (jgroup == -1) error->all(FLERR,"Compute group/group group ID does not exist"); jgroupbit = group->bitmask[jgroup]; // need an occasional half neighbor list diff --git a/src/compute_gyration.cpp b/src/compute_gyration.cpp index de2ebf8f1b..f192ea3d69 100644 --- a/src/compute_gyration.cpp +++ b/src/compute_gyration.cpp @@ -23,7 +23,7 @@ using namespace LAMMPS_NS; ComputeGyration::ComputeGyration(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute gyration command"); + if (narg != 3) error->all(FLERR,"Illegal compute gyration command"); scalar_flag = 1; extscalar = 0; diff --git a/src/compute_gyration_molecule.cpp b/src/compute_gyration_molecule.cpp index 80fdca5fa0..dd96079d21 100644 --- a/src/compute_gyration_molecule.cpp +++ b/src/compute_gyration_molecule.cpp @@ -27,10 +27,10 @@ ComputeGyrationMolecule::ComputeGyrationMolecule(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute gyration/molecule command"); + if (narg != 3) error->all(FLERR,"Illegal compute gyration/molecule command"); if (atom->molecular == 0) - error->all("Compute gyration/molecule requires molecular atom style"); + error->all(FLERR,"Compute gyration/molecule requires molecular atom style"); vector_flag = 1; extvector = 0; @@ -93,7 +93,7 @@ void ComputeGyrationMolecule::init() { int ntmp = molecules_in_group(idlo,idhi); if (ntmp != nmolecules) - error->all("Molecule count changed in compute gyration/molecule"); + error->all(FLERR,"Molecule count changed in compute gyration/molecule"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_heat_flux.cpp b/src/compute_heat_flux.cpp index 28be7c5942..f5a38a5656 100644 --- a/src/compute_heat_flux.cpp +++ b/src/compute_heat_flux.cpp @@ -35,7 +35,7 @@ using namespace LAMMPS_NS; ComputeHeatFlux::ComputeHeatFlux(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 6) error->all("Illegal compute heat/flux command"); + if (narg != 6) error->all(FLERR,"Illegal compute heat/flux command"); vector_flag = 1; size_vector = 6; @@ -60,13 +60,13 @@ ComputeHeatFlux::ComputeHeatFlux(LAMMPS *lmp, int narg, char **arg) : int ipe = modify->find_compute(id_pe); int istress = modify->find_compute(id_stress); if (ike < 0 || ipe < 0 || istress < 0) - error->all("Could not find compute heat/flux compute ID"); + error->all(FLERR,"Could not find compute heat/flux compute ID"); if (strcmp(modify->compute[ike]->style,"ke/atom") != 0) - error->all("Compute heat/flux compute ID does not compute ke/atom"); + error->all(FLERR,"Compute heat/flux compute ID does not compute ke/atom"); if (modify->compute[ipe]->peatomflag == 0) - error->all("Compute heat/flux compute ID does not compute pe/atom"); + error->all(FLERR,"Compute heat/flux compute ID does not compute pe/atom"); if (modify->compute[istress]->pressatomflag == 0) - error->all("Compute heat/flux compute ID does not compute stress/atom"); + error->all(FLERR,"Compute heat/flux compute ID does not compute stress/atom"); vector = new double[6]; } @@ -91,7 +91,7 @@ void ComputeHeatFlux::init() int ipe = modify->find_compute(id_pe); int istress = modify->find_compute(id_stress); if (ike < 0 || ipe < 0 || istress < 0) - error->all("Could not find compute heat/flux compute ID"); + error->all(FLERR,"Could not find compute heat/flux compute ID"); c_ke = modify->compute[ike]; c_pe = modify->compute[ipe]; diff --git a/src/compute_improper_local.cpp b/src/compute_improper_local.cpp index 65e4ec1cc9..7162277c39 100644 --- a/src/compute_improper_local.cpp +++ b/src/compute_improper_local.cpp @@ -34,10 +34,10 @@ using namespace LAMMPS_NS; ComputeImproperLocal::ComputeImproperLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute improper/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute improper/local command"); if (atom->avec->impropers_allow == 0) - error->all("Compute improper/local used when impropers are not allowed"); + error->all(FLERR,"Compute improper/local used when impropers are not allowed"); local_flag = 1; nvalues = narg - 3; @@ -51,7 +51,7 @@ ComputeImproperLocal::ComputeImproperLocal(LAMMPS *lmp, int narg, char **arg) : for (int iarg = 3; iarg < narg; iarg++) { i = iarg-3; if (strcmp(arg[iarg],"chi") == 0) cflag = nvalues++; - else error->all("Invalid keyword in compute improper/local command"); + else error->all(FLERR,"Invalid keyword in compute improper/local command"); } nmax = 0; @@ -72,7 +72,7 @@ ComputeImproperLocal::~ComputeImproperLocal() void ComputeImproperLocal::init() { if (force->improper == NULL) - error->all("No improper style is defined for compute improper/local"); + error->all(FLERR,"No improper style is defined for compute improper/local"); // do initial memory allocation so that memory_usage() is correct diff --git a/src/compute_ke.cpp b/src/compute_ke.cpp index 2db20db761..629f1488e1 100644 --- a/src/compute_ke.cpp +++ b/src/compute_ke.cpp @@ -27,7 +27,7 @@ using namespace LAMMPS_NS; ComputeKE::ComputeKE(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute ke command"); + if (narg != 3) error->all(FLERR,"Illegal compute ke command"); scalar_flag = 1; extscalar = 1; diff --git a/src/compute_ke_atom.cpp b/src/compute_ke_atom.cpp index 0d6fc2d9c7..6d9d45268f 100644 --- a/src/compute_ke_atom.cpp +++ b/src/compute_ke_atom.cpp @@ -28,7 +28,7 @@ using namespace LAMMPS_NS; ComputeKEAtom::ComputeKEAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute ke/atom command"); + if (narg != 3) error->all(FLERR,"Illegal compute ke/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -52,7 +52,7 @@ void ComputeKEAtom::init() for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"ke/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning("More than one compute ke/atom"); + error->warning(FLERR,"More than one compute ke/atom"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_msd.cpp b/src/compute_msd.cpp index 3fcb99e89c..bf2d00332e 100644 --- a/src/compute_msd.cpp +++ b/src/compute_msd.cpp @@ -28,7 +28,7 @@ using namespace LAMMPS_NS; ComputeMSD::ComputeMSD(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute msd command"); + if (narg < 3) error->all(FLERR,"Illegal compute msd command"); vector_flag = 1; size_vector = 4; @@ -41,12 +41,12 @@ ComputeMSD::ComputeMSD(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"com") == 0) { - if (iarg+2 > narg) error->all("Illegal compute msd command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute msd command"); if (strcmp(arg[iarg+1],"no") == 0) comflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) comflag = 1; - else error->all("Illegal compute msd command"); + else error->all(FLERR,"Illegal compute msd command"); iarg += 2; - } else error->all("Illegal compute msd command"); + } else error->all(FLERR,"Illegal compute msd command"); } // create a new fix store/state style with or without com keyword @@ -93,7 +93,7 @@ void ComputeMSD::init() // set fix which stores original atom coords int ifix = modify->find_fix(id_fix); - if (ifix < 0) error->all("Could not find compute msd fix ID"); + if (ifix < 0) error->all(FLERR,"Could not find compute msd fix ID"); fix = modify->fix[ifix]; // nmsd = # of atoms in group diff --git a/src/compute_msd_molecule.cpp b/src/compute_msd_molecule.cpp index a4ad8b021c..de8d2f63c5 100644 --- a/src/compute_msd_molecule.cpp +++ b/src/compute_msd_molecule.cpp @@ -25,10 +25,10 @@ using namespace LAMMPS_NS; ComputeMSDMolecule::ComputeMSDMolecule(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute msd/molecule command"); + if (narg != 3) error->all(FLERR,"Illegal compute msd/molecule command"); if (atom->molecular == 0) - error->all("Compute msd/molecule requires molecular atom style"); + error->all(FLERR,"Compute msd/molecule requires molecular atom style"); array_flag = 1; size_array_cols = 4; @@ -103,7 +103,7 @@ void ComputeMSDMolecule::init() { int ntmp = molecules_in_group(idlo,idhi); if (ntmp != nmolecules) - error->all("Molecule count changed in compute msd/molecule"); + error->all(FLERR,"Molecule count changed in compute msd/molecule"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_pair.cpp b/src/compute_pair.cpp index 9617e016aa..e5e8dbda08 100644 --- a/src/compute_pair.cpp +++ b/src/compute_pair.cpp @@ -28,8 +28,8 @@ enum{EPAIR,EVDWL,ECOUL}; ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4 || narg > 5) error->all("Illegal compute pair command"); - if (igroup) error->all("Compute pair must use group all"); + if (narg < 4 || narg > 5) error->all(FLERR,"Illegal compute pair command"); + if (igroup) error->all(FLERR,"Compute pair must use group all"); scalar_flag = 1; extscalar = 1; @@ -47,7 +47,7 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : } else evalue = EPAIR; pair = force->pair_match(pstyle,1); - if (!pair) error->all("Unrecognized pair style in compute pair command"); + if (!pair) error->all(FLERR,"Unrecognized pair style in compute pair command"); npair = pair->nextra; if (npair) { @@ -75,7 +75,7 @@ void ComputePair::init() // recheck for pair style in case it has been deleted pair = force->pair_match(pstyle,1); - if (!pair) error->all("Unrecognized pair style in compute pair command"); + if (!pair) error->all(FLERR,"Unrecognized pair style in compute pair command"); } /* ---------------------------------------------------------------------- */ @@ -84,7 +84,7 @@ double ComputePair::compute_scalar() { invoked_scalar = update->ntimestep; if (update->eflag_global != invoked_scalar) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); double eng; if (evalue == EPAIR) eng = pair->eng_vdwl + pair->eng_coul; @@ -101,7 +101,7 @@ void ComputePair::compute_vector() { invoked_vector = update->ntimestep; if (update->eflag_global != invoked_vector) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); for (int i = 0; i < npair; i++) one[i] = pair->pvector[i]; diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp index aa209f2454..8c35f01702 100644 --- a/src/compute_pair_local.cpp +++ b/src/compute_pair_local.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute pair/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute pair/local command"); local_flag = 1; nvalues = narg - 3; @@ -50,7 +50,7 @@ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[iarg],"dist") == 0) dflag = nvalues++; else if (strcmp(arg[iarg],"eng") == 0) eflag = nvalues++; else if (strcmp(arg[iarg],"force") == 0) fflag = nvalues++; - else error->all("Invalid keyword in compute pair/local command"); + else error->all(FLERR,"Invalid keyword in compute pair/local command"); } nmax = 0; @@ -71,9 +71,9 @@ ComputePairLocal::~ComputePairLocal() void ComputePairLocal::init() { if (force->pair == NULL) - error->all("No pair style is defined for compute pair/local"); + error->all(FLERR,"No pair style is defined for compute pair/local"); if (force->pair->single_enable == 0) - error->all("Pair style does not support compute pair/local"); + error->all(FLERR,"Pair style does not support compute pair/local"); // need an occasional half neighbor list diff --git a/src/compute_pe.cpp b/src/compute_pe.cpp index 1d72d37fed..c153e15d8a 100644 --- a/src/compute_pe.cpp +++ b/src/compute_pe.cpp @@ -34,8 +34,8 @@ using namespace LAMMPS_NS; ComputePE::ComputePE(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute pe command"); - if (igroup) error->all("Compute pe must use group all"); + if (narg < 3) error->all(FLERR,"Illegal compute pe command"); + if (igroup) error->all(FLERR,"Compute pe must use group all"); scalar_flag = 1; extscalar = 1; @@ -60,7 +60,7 @@ ComputePE::ComputePE(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1; else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1; else if (strcmp(arg[iarg],"kspace") == 0) kspaceflag = 1; - else error->all("Illegal compute pe command"); + else error->all(FLERR,"Illegal compute pe command"); iarg++; } } @@ -72,7 +72,7 @@ double ComputePE::compute_scalar() { invoked_scalar = update->ntimestep; if (update->eflag_global != invoked_scalar) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); double one = 0.0; if (pairflag && force->pair) diff --git a/src/compute_pe_atom.cpp b/src/compute_pe_atom.cpp index 3d424e61c2..20a16ae5b0 100755 --- a/src/compute_pe_atom.cpp +++ b/src/compute_pe_atom.cpp @@ -32,7 +32,7 @@ using namespace LAMMPS_NS; ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute pe/atom command"); + if (narg < 3) error->all(FLERR,"Illegal compute pe/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -53,7 +53,7 @@ ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1; else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1; else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1; - else error->all("Illegal compute pe/atom command"); + else error->all(FLERR,"Illegal compute pe/atom command"); iarg++; } } @@ -77,7 +77,7 @@ void ComputePEAtom::compute_peratom() invoked_peratom = update->ntimestep; if (update->eflag_atom != invoked_peratom) - error->all("Per-atom energy was not tallied on needed timestep"); + error->all(FLERR,"Per-atom energy was not tallied on needed timestep"); // grow local energy array if necessary // needs to be atom->nmax in length diff --git a/src/compute_pressure.cpp b/src/compute_pressure.cpp index 94391ce527..edd6910cce 100644 --- a/src/compute_pressure.cpp +++ b/src/compute_pressure.cpp @@ -36,8 +36,8 @@ using namespace LAMMPS_NS; ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute pressure command"); - if (igroup) error->all("Compute pressure must use group all"); + if (narg < 4) error->all(FLERR,"Illegal compute pressure command"); + if (igroup) error->all(FLERR,"Compute pressure must use group all"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -55,9 +55,9 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Could not find compute pressure temperature ID"); + error->all(FLERR,"Could not find compute pressure temperature ID"); if (modify->compute[icompute]->tempflag == 0) - error->all("Compute pressure temperature ID does not compute temperature"); + error->all(FLERR,"Compute pressure temperature ID does not compute temperature"); // process optional args @@ -85,7 +85,7 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : pairflag = 1; bondflag = angleflag = dihedralflag = improperflag = 1; kspaceflag = fixflag = 1; - } else error->all("Illegal compute pressure command"); + } else error->all(FLERR,"Illegal compute pressure command"); iarg++; } } @@ -117,7 +117,7 @@ void ComputePressure::init() int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Could not find compute pressure temperature ID"); + error->all(FLERR,"Could not find compute pressure temperature ID"); temperature = modify->compute[icompute]; // detect contributions to virial @@ -166,7 +166,7 @@ double ComputePressure::compute_scalar() { invoked_scalar = update->ntimestep; if (update->vflag_global != invoked_scalar) - error->all("Virial was not tallied on needed timestep"); + error->all(FLERR,"Virial was not tallied on needed timestep"); // invoke temperature it it hasn't been already @@ -207,7 +207,7 @@ void ComputePressure::compute_vector() { invoked_vector = update->ntimestep; if (update->vflag_global != invoked_vector) - error->all("Virial was not tallied on needed timestep"); + error->all(FLERR,"Virial was not tallied on needed timestep"); // invoke temperature if it hasn't been already diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index b145139d19..f7605d5552 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -27,7 +27,7 @@ using namespace LAMMPS_NS; ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute property/atom command"); + if (narg < 4) error->all(FLERR,"Illegal compute property/atom command"); peratom_flag = 1; nvalues = narg - 3; @@ -47,7 +47,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_id; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_molecule; } else if (strcmp(arg[iarg],"type") == 0) { @@ -107,144 +107,144 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_mu; } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all("Compute property/atom for " + if (!avec) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqz; } else if (strcmp(arg[iarg],"spin") == 0) { if (!atom->spin_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_spin; } else if (strcmp(arg[iarg],"eradius") == 0) { if (!atom->eradius_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_eradius; } else if (strcmp(arg[iarg],"ervel") == 0) { if (!atom->ervel_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_ervel; } else if (strcmp(arg[iarg],"erforce") == 0) { if (!atom->erforce_flag) - error->all("Compute property/atom for " + error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_erforce; - } else error->all("Invalid keyword in compute property/atom command"); + } else error->all(FLERR,"Invalid keyword in compute property/atom command"); } nmax = 0; diff --git a/src/compute_property_local.cpp b/src/compute_property_local.cpp index a0e615bc41..48ab145d8c 100644 --- a/src/compute_property_local.cpp +++ b/src/compute_property_local.cpp @@ -35,7 +35,7 @@ enum{NONE,NEIGH,PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER}; ComputePropertyLocal::ComputePropertyLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute property/local command"); + if (narg < 4) error->all(FLERR,"Illegal compute property/local command"); local_flag = 1; nvalues = narg - 3; @@ -53,127 +53,127 @@ ComputePropertyLocal::ComputePropertyLocal(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[iarg],"natom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom1; if (kindflag != NONE && kindflag != NEIGH) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"natom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom2; if (kindflag != NONE && kindflag != NEIGH) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"patom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom1; if (kindflag != NONE && kindflag != PAIR) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"patom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom2; if (kindflag != NONE && kindflag != PAIR) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"batom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_batom1; if (kindflag != NONE && kindflag != BOND) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"batom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_batom2; if (kindflag != NONE && kindflag != BOND) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"btype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_btype; if (kindflag != NONE && kindflag != BOND) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"aatom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom1; if (kindflag != NONE && kindflag != ANGLE) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"aatom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom2; if (kindflag != NONE && kindflag != ANGLE) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"aatom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom3; if (kindflag != NONE && kindflag != ANGLE) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"atype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_atype; if (kindflag != NONE && kindflag != ANGLE) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"datom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom1; if (kindflag != NONE && kindflag != DIHEDRAL) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom2; if (kindflag != NONE && kindflag != DIHEDRAL) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom3; if (kindflag != NONE && kindflag != DIHEDRAL) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom4") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom4; if (kindflag != NONE && kindflag != DIHEDRAL) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"dtype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_dtype; if (kindflag != NONE && kindflag != DIHEDRAL) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"iatom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom1; if (kindflag != NONE && kindflag != IMPROPER) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom2; if (kindflag != NONE && kindflag != IMPROPER) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom3; if (kindflag != NONE && kindflag != IMPROPER) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom4") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom4; if (kindflag != NONE && kindflag != IMPROPER) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"itype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_itype; if (kindflag != NONE && kindflag != IMPROPER) - error->all("Compute property/local cannot use these inputs together"); + error->all(FLERR,"Compute property/local cannot use these inputs together"); kindflag = IMPROPER; - } else error->all("Invalid keyword in compute property/local command"); + } else error->all(FLERR,"Invalid keyword in compute property/local command"); } // error check if (kindflag == BOND && atom->avec->bonds_allow == 0) - error->all("Compute property/local for property that isn't allocated"); + error->all(FLERR,"Compute property/local for property that isn't allocated"); if (kindflag == ANGLE && atom->avec->angles_allow == 0) - error->all("Compute property/local for property that isn't allocated"); + error->all(FLERR,"Compute property/local for property that isn't allocated"); if (kindflag == DIHEDRAL && atom->avec->dihedrals_allow == 0) - error->all("Compute property/local for property that isn't allocated"); + error->all(FLERR,"Compute property/local for property that isn't allocated"); if (kindflag == IMPROPER && atom->avec->impropers_allow == 0) - error->all("Compute property/local for property that isn't allocated"); + error->all(FLERR,"Compute property/local for property that isn't allocated"); nmax = 0; vector = NULL; @@ -197,9 +197,9 @@ void ComputePropertyLocal::init() { if (kindflag == NEIGH || kindflag == PAIR) { if (force->pair == NULL) - error->all("No pair style is defined for compute property/local"); + error->all(FLERR,"No pair style is defined for compute property/local"); if (force->pair->single_enable == 0) - error->all("Pair style does not support compute property/local"); + error->all(FLERR,"Pair style does not support compute property/local"); } // for NEIGH/PAIR need an occasional half neighbor list diff --git a/src/compute_property_molecule.cpp b/src/compute_property_molecule.cpp index 7ccf0208a1..65ec20ef03 100644 --- a/src/compute_property_molecule.cpp +++ b/src/compute_property_molecule.cpp @@ -26,10 +26,10 @@ ComputePropertyMolecule:: ComputePropertyMolecule(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute property/molecule command"); + if (narg < 4) error->all(FLERR,"Illegal compute property/molecule command"); if (atom->molecular == 0) - error->all("Compute property/molecule requires molecular atom style"); + error->all(FLERR,"Compute property/molecule requires molecular atom style"); nvalues = narg - 3; @@ -43,7 +43,7 @@ ComputePropertyMolecule(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyMolecule::pack_mol; else if (strcmp(arg[iarg],"count") == 0) pack_choice[i] = &ComputePropertyMolecule::pack_count; - else error->all("Invalid keyword in compute property/molecule command"); + else error->all(FLERR,"Invalid keyword in compute property/molecule command"); } // setup molecule-based data @@ -93,7 +93,7 @@ void ComputePropertyMolecule::init() { int ntmp = molecules_in_group(idlo,idhi); if (ntmp != nmolecules) - error->all("Molecule count changed in compute property/molecule"); + error->all(FLERR,"Molecule count changed in compute property/molecule"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_rdf.cpp b/src/compute_rdf.cpp index 96a11ab273..9dbe3aded0 100644 --- a/src/compute_rdf.cpp +++ b/src/compute_rdf.cpp @@ -38,13 +38,13 @@ using namespace LAMMPS_NS; ComputeRDF::ComputeRDF(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4 || (narg-4) % 2) error->all("Illegal compute rdf command"); + if (narg < 4 || (narg-4) % 2) error->all(FLERR,"Illegal compute rdf command"); array_flag = 1; extarray = 0; nbin = atoi(arg[3]); - if (nbin < 1) error->all("Illegal compute rdf command"); + if (nbin < 1) error->all(FLERR,"Illegal compute rdf command"); if (narg == 4) npairs = 1; else npairs = (narg-4)/2; @@ -71,7 +71,7 @@ ComputeRDF::ComputeRDF(LAMMPS *lmp, int narg, char **arg) : force->bounds(arg[iarg],atom->ntypes,ilo[npairs],ihi[npairs]); force->bounds(arg[iarg+1],atom->ntypes,jlo[npairs],jhi[npairs]); if (ilo[npairs] > ihi[npairs] || jlo[npairs] > jhi[npairs]) - error->all("Illegal compute rdf command"); + error->all(FLERR,"Illegal compute rdf command"); npairs++; iarg += 2; } @@ -120,7 +120,7 @@ void ComputeRDF::init() int i,m; if (force->pair) delr = force->pair->cutforce / nbin; - else error->all("Compute rdf requires a pair style be defined"); + else error->all(FLERR,"Compute rdf requires a pair style be defined"); delrinv = 1.0/delr; // set 1st column of output array to bin coords diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index 8764afe75b..3872661a67 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -39,8 +39,6 @@ enum{PERATOM,LOCAL}; #define INVOKED_PERATOM 8 #define INVOKED_LOCAL 16 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ @@ -50,14 +48,14 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : { int iarg; if (strcmp(style,"reduce") == 0) { - if (narg < 5) error->all("Illegal compute reduce command"); + if (narg < 5) error->all(FLERR,"Illegal compute reduce command"); idregion = NULL; iarg = 3; } else if (strcmp(style,"reduce/region") == 0) { - if (narg < 6) error->all("Illegal compute reduce/region command"); + if (narg < 6) error->all(FLERR,"Illegal compute reduce/region command"); iregion = domain->find_region(arg[3]); if (iregion == -1) - error->all("Region ID for compute reduce/region does not exist"); + error->all(FLERR,"Region ID for compute reduce/region does not exist"); int n = strlen(arg[3]) + 1; idregion = new char[n]; strcpy(idregion,arg[3]); @@ -68,7 +66,7 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg],"min") == 0) mode = MINN; else if (strcmp(arg[iarg],"max") == 0) mode = MAXX; else if (strcmp(arg[iarg],"ave") == 0) mode = AVE; - else error->all("Illegal compute reduce command"); + else error->all(FLERR,"Illegal compute reduce command"); iarg++; MPI_Comm_rank(world,&me); @@ -129,7 +127,7 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal compute reduce command"); + error->all(FLERR,"Illegal compute reduce command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -152,19 +150,19 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"replace") == 0) { - if (iarg+3 > narg) error->all("Illegal compute reduce command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal compute reduce command"); if (mode != MINN && mode != MAXX) - error->all("Compute reduce replace requires min or max mode"); + error->all(FLERR,"Compute reduce replace requires min or max mode"); int col1 = atoi(arg[iarg+1]) - 1; int col2 = atoi(arg[iarg+2]) - 1; if (col1 < 0 || col1 >= nvalues || col2 < 0 || col2 >= nvalues) - error->all("Illegal compute reduce command"); - if (col1 == col2) error->all("Illegal compute reduce command"); + error->all(FLERR,"Illegal compute reduce command"); + if (col1 == col2) error->all(FLERR,"Illegal compute reduce command"); if (replace[col1] >= 0 || replace[col2] >= 0) - error->all("Invalid replace values in compute reduce"); + error->all(FLERR,"Invalid replace values in compute reduce"); replace[col1] = col2; iarg += 3; - } else error->all("Illegal compute reduce command"); + } else error->all(FLERR,"Illegal compute reduce command"); } // delete replace if not set @@ -186,69 +184,69 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : else if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for compute reduce does not exist"); + error->all(FLERR,"Compute ID for compute reduce does not exist"); if (modify->compute[icompute]->peratom_flag) { flavor[i] = PERATOM; if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Compute reduce compute does not " + error->all(FLERR,"Compute reduce compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Compute reduce compute does not " + error->all(FLERR,"Compute reduce compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Compute reduce compute array is accessed out-of-range"); + error->all(FLERR,"Compute reduce compute array is accessed out-of-range"); } else if (modify->compute[icompute]->local_flag) { flavor[i] = LOCAL; if (argindex[i] == 0 && modify->compute[icompute]->size_local_cols != 0) - error->all("Compute reduce compute does not " + error->all(FLERR,"Compute reduce compute does not " "calculate a local vector"); if (argindex[i] && modify->compute[icompute]->size_local_cols == 0) - error->all("Compute reduce compute does not " + error->all(FLERR,"Compute reduce compute does not " "calculate a local array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_local_cols) - error->all("Compute reduce compute array is accessed out-of-range"); - } else error->all("Compute reduce compute calculates global values"); + error->all(FLERR,"Compute reduce compute array is accessed out-of-range"); + } else error->all(FLERR,"Compute reduce compute calculates global values"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for compute reduce does not exist"); + error->all(FLERR,"Fix ID for compute reduce does not exist"); if (modify->fix[ifix]->peratom_flag) { flavor[i] = PERATOM; if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Compute reduce fix does not " + error->all(FLERR,"Compute reduce fix does not " "calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Compute reduce fix does not " + error->all(FLERR,"Compute reduce fix does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Compute reduce fix array is accessed out-of-range"); + error->all(FLERR,"Compute reduce fix array is accessed out-of-range"); } else if (modify->fix[ifix]->local_flag) { flavor[i] = LOCAL; if (argindex[i] == 0 && modify->fix[ifix]->size_local_cols != 0) - error->all("Compute reduce fix does not " + error->all(FLERR,"Compute reduce fix does not " "calculate a local vector"); if (argindex[i] && modify->fix[ifix]->size_local_cols == 0) - error->all("Compute reduce fix does not " + error->all(FLERR,"Compute reduce fix does not " "calculate a local array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_local_cols) - error->all("Compute reduce fix array is accessed out-of-range"); - } else error->all("Compute reduce fix calculates global values"); + error->all(FLERR,"Compute reduce fix array is accessed out-of-range"); + } else error->all(FLERR,"Compute reduce fix calculates global values"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for compute reduce does not exist"); + error->all(FLERR,"Variable name for compute reduce does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all("Compute reduce variable is not atom-style variable"); + error->all(FLERR,"Compute reduce variable is not atom-style variable"); flavor[i] = PERATOM; } } @@ -307,19 +305,19 @@ void ComputeReduce::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for compute reduce does not exist"); + error->all(FLERR,"Compute ID for compute reduce does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for compute reduce does not exist"); + error->all(FLERR,"Fix ID for compute reduce does not exist"); value2index[m] = ifix; } else if (which[m] == VARIABLE) { int ivariable = input->variable->find(ids[m]); if (ivariable < 0) - error->all("Variable name for compute reduce does not exist"); + error->all(FLERR,"Variable name for compute reduce does not exist"); value2index[m] = ivariable; } else value2index[m] = -1; @@ -330,7 +328,7 @@ void ComputeReduce::init() if (idregion) { iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for compute reduce/region does not exist"); + error->all(FLERR,"Region ID for compute reduce/region does not exist"); } } @@ -531,7 +529,7 @@ double ComputeReduce::compute_one(int m, int flag) } else if (which[m] == FIX) { if (update->ntimestep % modify->fix[vidx]->peratom_freq) - error->all("Fix used in compute reduce not computed at compatible time"); + error->all(FLERR,"Fix used in compute reduce not computed at compatible time"); Fix *fix = modify->fix[vidx]; if (flavor[m] == PERATOM) { diff --git a/src/compute_reduce_region.cpp b/src/compute_reduce_region.cpp index eff9416b1c..648b90e1d8 100644 --- a/src/compute_reduce_region.cpp +++ b/src/compute_reduce_region.cpp @@ -156,7 +156,7 @@ double ComputeReduceRegion::compute_one(int m, int flag) } else if (which[m] == FIX) { if (update->ntimestep % modify->fix[n]->peratom_freq) - error->all("Fix used in compute reduce not computed at compatible time"); + error->all(FLERR,"Fix used in compute reduce not computed at compatible time"); Fix *fix = modify->fix[n]; if (flavor[m] == PERATOM) { diff --git a/src/compute_slice.cpp b/src/compute_slice.cpp index 51e7747e36..85e9230499 100644 --- a/src/compute_slice.cpp +++ b/src/compute_slice.cpp @@ -33,7 +33,7 @@ enum{COMPUTE,FIX}; ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 7) error->all("Illegal compute slice command"); + if (narg < 7) error->all(FLERR,"Illegal compute slice command"); MPI_Comm_rank(world,&me); @@ -42,7 +42,7 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : nskip = atoi(arg[5]); if (nstart < 1 || nstop < nstart || nskip < 1) - error->all("Illegal compute slice command"); + error->all(FLERR,"Illegal compute slice command"); // parse remaining values until one isn't recognized @@ -65,7 +65,7 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal compute slice command"); + error->all(FLERR,"Illegal compute slice command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -76,7 +76,7 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : nvalues++; delete [] suffix; - } else error->all("Illegal compute slice command"); + } else error->all(FLERR,"Illegal compute slice command"); } // setup and error check @@ -85,38 +85,38 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for compute slice does not exist"); + error->all(FLERR,"Compute ID for compute slice does not exist"); if (modify->compute[icompute]->vector_flag) { if (argindex[i]) - error->all("Compute slice compute does not calculate a global array"); + error->all(FLERR,"Compute slice compute does not calculate a global array"); if (nstop > modify->compute[icompute]->size_vector) - error->all("Compute slice compute vector is accessed out-of-range"); + error->all(FLERR,"Compute slice compute vector is accessed out-of-range"); } else if (modify->compute[icompute]->array_flag) { if (argindex[i] == 0) - error->all("Compute slice compute does not calculate a global vector"); + error->all(FLERR,"Compute slice compute does not calculate a global vector"); if (argindex[i] > modify->compute[icompute]->size_array_cols) - error->all("Compute slice compute array is accessed out-of-range"); + error->all(FLERR,"Compute slice compute array is accessed out-of-range"); if (nstop > modify->compute[icompute]->size_array_rows) - error->all("Compute slice compute array is accessed out-of-range"); - } else error->all("Compute slice compute does not calculate " + error->all(FLERR,"Compute slice compute array is accessed out-of-range"); + } else error->all(FLERR,"Compute slice compute does not calculate " "global vector or array"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for compute slice does not exist"); + error->all(FLERR,"Fix ID for compute slice does not exist"); if (modify->fix[ifix]->vector_flag) { if (argindex[i]) - error->all("Compute slice fix does not calculate a global array"); + error->all(FLERR,"Compute slice fix does not calculate a global array"); if (nstop > modify->fix[ifix]->size_vector) - error->all("Compute slice fix vector is accessed out-of-range"); + error->all(FLERR,"Compute slice fix vector is accessed out-of-range"); } else if (modify->fix[ifix]->array_flag) { if (argindex[i] == 0) - error->all("Compute slice fix does not calculate a global vector"); + error->all(FLERR,"Compute slice fix does not calculate a global vector"); if (argindex[i] > modify->fix[ifix]->size_array_cols) - error->all("Compute slice fix array is accessed out-of-range"); + error->all(FLERR,"Compute slice fix array is accessed out-of-range"); if (nstop > modify->fix[ifix]->size_array_rows) - error->all("Compute slice fix array is accessed out-of-range"); - } else error->all("Compute slice fix does not calculate " + error->all(FLERR,"Compute slice fix array is accessed out-of-range"); + } else error->all(FLERR,"Compute slice fix does not calculate " "global vector or array"); } } @@ -217,12 +217,12 @@ void ComputeSlice::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for compute slice does not exist"); + error->all(FLERR,"Compute ID for compute slice does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for compute slice does not exist"); + error->all(FLERR,"Fix ID for compute slice does not exist"); value2index[m] = ifix; } } @@ -291,7 +291,7 @@ void ComputeSlice::extract_one(int m, double *vec, int stride) } else if (which[m] == FIX) { if (update->ntimestep % modify->fix[value2index[m]]->global_freq) - error->all("Fix used in compute slice not computed at compatible time"); + error->all(FLERR,"Fix used in compute slice not computed at compatible time"); Fix *fix = modify->fix[value2index[m]]; if (argindex[m] == 0) { diff --git a/src/compute_stress_atom.cpp b/src/compute_stress_atom.cpp index b17d4fc6a2..5560221225 100644 --- a/src/compute_stress_atom.cpp +++ b/src/compute_stress_atom.cpp @@ -35,7 +35,7 @@ using namespace LAMMPS_NS; ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute stress/atom command"); + if (narg < 3) error->all(FLERR,"Illegal compute stress/atom command"); peratom_flag = 1; size_peratom_cols = 6; @@ -66,7 +66,7 @@ ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) : pairflag = 1; bondflag = angleflag = dihedralflag = improperflag = 1; fixflag = 1; - } else error->all("Illegal compute stress/atom command"); + } else error->all(FLERR,"Illegal compute stress/atom command"); iarg++; } } @@ -91,7 +91,7 @@ void ComputeStressAtom::compute_peratom() invoked_peratom = update->ntimestep; if (update->vflag_atom != invoked_peratom) - error->all("Per-atom virial was not tallied on needed timestep"); + error->all(FLERR,"Per-atom virial was not tallied on needed timestep"); // grow local stress array if necessary // needs to be atom->nmax in length diff --git a/src/compute_temp.cpp b/src/compute_temp.cpp index 5ba16633f4..ab63a8c9f6 100644 --- a/src/compute_temp.cpp +++ b/src/compute_temp.cpp @@ -30,7 +30,7 @@ using namespace LAMMPS_NS; ComputeTemp::ComputeTemp(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute temp command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp command"); scalar_flag = vector_flag = 1; size_vector = 6; diff --git a/src/compute_temp_com.cpp b/src/compute_temp_com.cpp index 22cfab7610..d344d3d214 100644 --- a/src/compute_temp_com.cpp +++ b/src/compute_temp_com.cpp @@ -27,15 +27,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ ComputeTempCOM::ComputeTempCOM(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute temp command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp command"); scalar_flag = vector_flag = 1; size_vector = 6; diff --git a/src/compute_temp_deform.cpp b/src/compute_temp_deform.cpp index 665f904fdb..87fcb02eae 100644 --- a/src/compute_temp_deform.cpp +++ b/src/compute_temp_deform.cpp @@ -39,7 +39,7 @@ enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp ComputeTempDeform::ComputeTempDeform(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 3) error->all("Illegal compute temp/deform command"); + if (narg != 3) error->all(FLERR,"Illegal compute temp/deform command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -78,12 +78,12 @@ void ComputeTempDeform::init() if (strcmp(modify->fix[i]->style,"deform") == 0) { if (((FixDeform *) modify->fix[i])->remapflag == X_REMAP && comm->me == 0) - error->warning("Using compute temp/deform with inconsistent " + error->warning(FLERR,"Using compute temp/deform with inconsistent " "fix deform remap option"); break; } if (i == modify->nfix && comm->me == 0) - error->warning("Using compute temp/deform with no fix deform defined"); + error->warning(FLERR,"Using compute temp/deform with no fix deform defined"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_temp_partial.cpp b/src/compute_temp_partial.cpp index 96fd04037c..bfb2088e56 100644 --- a/src/compute_temp_partial.cpp +++ b/src/compute_temp_partial.cpp @@ -31,7 +31,7 @@ using namespace LAMMPS_NS; ComputeTempPartial::ComputeTempPartial(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 6) error->all("Illegal compute temp/partial command"); + if (narg != 6) error->all(FLERR,"Illegal compute temp/partial command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -44,7 +44,7 @@ ComputeTempPartial::ComputeTempPartial(LAMMPS *lmp, int narg, char **arg) : yflag = atoi(arg[4]); zflag = atoi(arg[5]); if (zflag && domain->dimension == 2) - error->all("Compute temp/partial cannot use vz for 2d systemx"); + error->all(FLERR,"Compute temp/partial cannot use vz for 2d systemx"); maxbias = 0; vbiasall = NULL; diff --git a/src/compute_temp_profile.cpp b/src/compute_temp_profile.cpp index 399b897df8..a242aba339 100644 --- a/src/compute_temp_profile.cpp +++ b/src/compute_temp_profile.cpp @@ -27,15 +27,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ ComputeTempProfile::ComputeTempProfile(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 7) error->all("Illegal compute temp/profile command"); + if (narg < 7) error->all(FLERR,"Illegal compute temp/profile command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -48,7 +45,7 @@ ComputeTempProfile::ComputeTempProfile(LAMMPS *lmp, int narg, char **arg) : yflag = atoi(arg[4]); zflag = atoi(arg[5]); if (zflag && domain->dimension == 2) - error->all("Compute temp/profile cannot use vz for 2d systemx"); + error->all(FLERR,"Compute temp/profile cannot use vz for 2d systemx"); ncount = 0; ivx = ivy = ivz = 0; @@ -59,43 +56,43 @@ ComputeTempProfile::ComputeTempProfile(LAMMPS *lmp, int narg, char **arg) : nbinx = nbiny = nbinz = 1; if (strcmp(arg[6],"x") == 0) { - if (narg != 8) error->all("Illegal compute temp/profile command"); + if (narg != 8) error->all(FLERR,"Illegal compute temp/profile command"); nbinx = atoi(arg[7]); } else if (strcmp(arg[6],"y") == 0) { - if (narg != 8) error->all("Illegal compute temp/profile command"); + if (narg != 8) error->all(FLERR,"Illegal compute temp/profile command"); nbiny = atoi(arg[7]); } else if (strcmp(arg[6],"z") == 0) { - if (narg != 8) error->all("Illegal compute temp/profile command"); + if (narg != 8) error->all(FLERR,"Illegal compute temp/profile command"); if (domain->dimension == 2) - error->all("Compute temp/profile cannot bin z for 2d systems"); + error->all(FLERR,"Compute temp/profile cannot bin z for 2d systems"); nbinz = atoi(arg[7]); } else if (strcmp(arg[6],"xy") == 0) { - if (narg != 9) error->all("Illegal compute temp/profile command"); + if (narg != 9) error->all(FLERR,"Illegal compute temp/profile command"); nbinx = atoi(arg[7]); nbiny = atoi(arg[8]); } else if (strcmp(arg[6],"yz") == 0) { - if (narg != 9) error->all("Illegal compute temp/profile command"); + if (narg != 9) error->all(FLERR,"Illegal compute temp/profile command"); if (domain->dimension == 2) - error->all("Compute temp/profile cannot bin z for 2d systems"); + error->all(FLERR,"Compute temp/profile cannot bin z for 2d systems"); nbiny = atoi(arg[7]); nbinz = atoi(arg[8]); } else if (strcmp(arg[6],"xz") == 0) { - if (narg != 9) error->all("Illegal compute temp/profile command"); + if (narg != 9) error->all(FLERR,"Illegal compute temp/profile command"); if (domain->dimension == 2) - error->all("Compute temp/profile cannot bin z for 2d systems"); + error->all(FLERR,"Compute temp/profile cannot bin z for 2d systems"); nbinx = atoi(arg[7]); nbinz = atoi(arg[8]); } else if (strcmp(arg[6],"xyz") == 0) { - if (narg != 10) error->all("Illegal compute temp/profile command"); + if (narg != 10) error->all(FLERR,"Illegal compute temp/profile command"); if (domain->dimension == 2) - error->all("Compute temp/profile cannot bin z for 2d systems"); + error->all(FLERR,"Compute temp/profile cannot bin z for 2d systems"); nbinx = atoi(arg[7]); nbiny = atoi(arg[8]); nbinz = atoi(arg[9]); - } else error->all("Illegal compute temp/profile command"); + } else error->all(FLERR,"Illegal compute temp/profile command"); nbins = nbinx*nbiny*nbinz; - if (nbins <= 0) error->all("Illegal compute temp/profile command"); + if (nbins <= 0) error->all(FLERR,"Illegal compute temp/profile command"); memory->create(vbin,nbins,ncount+1,"temp/profile:vbin"); memory->create(binave,nbins,ncount+1,"temp/profile:binave"); diff --git a/src/compute_temp_ramp.cpp b/src/compute_temp_ramp.cpp index 1690e1224c..135a3eea6d 100644 --- a/src/compute_temp_ramp.cpp +++ b/src/compute_temp_ramp.cpp @@ -28,15 +28,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ ComputeTempRamp::ComputeTempRamp(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 9) error->all("Illegal compute temp command"); + if (narg < 9) error->all(FLERR,"Illegal compute temp command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -52,18 +49,18 @@ ComputeTempRamp::ComputeTempRamp(LAMMPS *lmp, int narg, char **arg) : int iarg = 9; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal compute temp/ramp command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/ramp command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal compute temp/ramp command"); + else error->all(FLERR,"Illegal compute temp/ramp command"); iarg += 2; - } else error->all("Illegal compute temp/ramp command"); + } else error->all(FLERR,"Illegal compute temp/ramp command"); } // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of compute temp/ramp with undefined lattice"); + error->all(FLERR,"Use of compute temp/ramp with undefined lattice"); if (scaleflag) { xscale = domain->lattice->xlattice; @@ -77,7 +74,7 @@ ComputeTempRamp::ComputeTempRamp(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[3],"vx") == 0) v_dim = 0; else if (strcmp(arg[3],"vy") == 0) v_dim = 1; else if (strcmp(arg[3],"vz") == 0) v_dim = 2; - else error->all("Illegal compute temp/ramp command"); + else error->all(FLERR,"Illegal compute temp/ramp command"); if (v_dim == 0) { v_lo = xscale*atof(arg[4]); @@ -93,7 +90,7 @@ ComputeTempRamp::ComputeTempRamp(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[6],"x") == 0) coord_dim = 0; else if (strcmp(arg[6],"y") == 0) coord_dim = 1; else if (strcmp(arg[6],"z") == 0) coord_dim = 2; - else error->all("Illegal compute temp/ramp command"); + else error->all(FLERR,"Illegal compute temp/ramp command"); if (coord_dim == 0) { coord_lo = xscale*atof(arg[7]); diff --git a/src/compute_temp_region.cpp b/src/compute_temp_region.cpp index b43af45de3..964f162d9f 100644 --- a/src/compute_temp_region.cpp +++ b/src/compute_temp_region.cpp @@ -30,11 +30,11 @@ using namespace LAMMPS_NS; ComputeTempRegion::ComputeTempRegion(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute temp/region command"); + if (narg != 4) error->all(FLERR,"Illegal compute temp/region command"); iregion = domain->find_region(arg[3]); if (iregion == -1) - error->all("Region ID for compute temp/region does not exist"); + error->all(FLERR,"Region ID for compute temp/region does not exist"); int n = strlen(arg[3]) + 1; idregion = new char[n]; strcpy(idregion,arg[3]); @@ -68,7 +68,7 @@ void ComputeTempRegion::init() iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for compute temp/region does not exist"); + error->all(FLERR,"Region ID for compute temp/region does not exist"); dof = 0.0; } diff --git a/src/compute_temp_sphere.cpp b/src/compute_temp_sphere.cpp index 246d58bae4..ed4a250085 100644 --- a/src/compute_temp_sphere.cpp +++ b/src/compute_temp_sphere.cpp @@ -35,7 +35,7 @@ enum{ROTATE,ALL}; ComputeTempSphere::ComputeTempSphere(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 3) error->all("Illegal compute temp/sphere command"); + if (narg < 3) error->all(FLERR,"Illegal compute temp/sphere command"); scalar_flag = vector_flag = 1; size_vector = 6; @@ -50,19 +50,19 @@ ComputeTempSphere::ComputeTempSphere(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"bias") == 0) { - if (iarg+2 > narg) error->all("Illegal compute temp/sphere command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/sphere command"); tempbias = 1; int n = strlen(arg[iarg+1]) + 1; id_bias = new char[n]; strcpy(id_bias,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"dof") == 0) { - if (iarg+2 > narg) error->all("Illegal compute temp/sphere command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/sphere command"); if (strcmp(arg[iarg+1],"rotate") == 0) mode = ROTATE; else if (strcmp(arg[iarg+1],"all") == 0) mode = ALL; - else error->all("Illegal compute temp/sphere command"); + else error->all(FLERR,"Illegal compute temp/sphere command"); iarg += 2; - } else error->all("Illegal compute temp/sphere command"); + } else error->all(FLERR,"Illegal compute temp/sphere command"); } vector = new double[6]; @@ -70,7 +70,7 @@ ComputeTempSphere::ComputeTempSphere(LAMMPS *lmp, int narg, char **arg) : // error checks if (!atom->sphere_flag) - error->all("Compute temp/sphere requires atom style sphere"); + error->all(FLERR,"Compute temp/sphere requires atom style sphere"); } /* ---------------------------------------------------------------------- */ @@ -87,14 +87,14 @@ void ComputeTempSphere::init() { if (tempbias) { int i = modify->find_compute(id_bias); - if (i < 0) error->all("Could not find compute ID for temperature bias"); + if (i < 0) error->all(FLERR,"Could not find compute ID for temperature bias"); tbias = modify->compute[i]; if (tbias->tempflag == 0) - error->all("Bias compute does not calculate temperature"); + error->all(FLERR,"Bias compute does not calculate temperature"); if (tbias->tempbias == 0) - error->all("Bias compute does not calculate a velocity bias"); + error->all(FLERR,"Bias compute does not calculate a velocity bias"); if (tbias->igroup != igroup) - error->all("Bias compute group does not match compute group"); + error->all(FLERR,"Bias compute group does not match compute group"); tbias->init(); if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; else tempbias = 1; diff --git a/src/compute_ti.cpp b/src/compute_ti.cpp index fd2a83ae0e..035fb35767 100644 --- a/src/compute_ti.cpp +++ b/src/compute_ti.cpp @@ -37,7 +37,7 @@ enum{PAIR,TAIL,KSPACE}; ComputeTI::ComputeTI(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all("Illegal compute ti command"); + if (narg < 4) error->all(FLERR,"Illegal compute ti command"); peflag = 1; scalar_flag = 1; @@ -47,7 +47,7 @@ ComputeTI::ComputeTI(LAMMPS *lmp, int narg, char **arg) : // terms come in triplets nterms = (narg-3) / 3; - if (narg != 3*nterms + 3) error->all("Illegal compute ti command"); + if (narg != 3*nterms + 3) error->all(FLERR,"Illegal compute ti command"); which = new int[nterms]; ivar1 = new int[nterms]; @@ -65,7 +65,7 @@ ComputeTI::ComputeTI(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; while (iarg < narg) { - if (iarg+3 > narg) error->all("Illegal compute ti command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal compute ti command"); if (strcmp(arg[iarg],"kspace") == 0) which[nterms] = KSPACE; else if (strcmp(arg[iarg],"tail") == 0) which[nterms] = TAIL; else { @@ -79,12 +79,12 @@ ComputeTI::ComputeTI(LAMMPS *lmp, int narg, char **arg) : int n = strlen(&arg[iarg+1][2]) + 1; var1[nterms] = new char[n]; strcpy(var1[nterms],&arg[iarg+1][2]); - } else error->all("Illegal compute ti command"); + } else error->all(FLERR,"Illegal compute ti command"); if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; var2[nterms] = new char[n]; strcpy(var2[nterms],&arg[iarg+2][2]); - } else error->all("Illegal compute ti command"); + } else error->all(FLERR,"Illegal compute ti command"); nterms++; iarg += 3; @@ -119,23 +119,23 @@ void ComputeTI::init() ivar1[m] = input->variable->find(var1[m]); ivar2[m] = input->variable->find(var2[m]); if (ivar1[m] < 0 || ivar2 < 0) - error->all("Variable name for compute ti does not exist"); + error->all(FLERR,"Variable name for compute ti does not exist"); if (!input->variable->equalstyle(ivar1[m]) || !input->variable->equalstyle(ivar2[m])) - error->all("Variable for compute ti is invalid style"); + error->all(FLERR,"Variable for compute ti is invalid style"); if (which[m] == PAIR) { pptr[m] = force->pair_match(pstyle[m],1); - if (pptr[m] == NULL) error->all("Compute ti pair style does not exist"); + if (pptr[m] == NULL) error->all(FLERR,"Compute ti pair style does not exist"); } else if (which[m] == TAIL) { if (force->pair == NULL || force->pair->tail_flag == 0) - error->all("Compute ti tail when pair style does not " + error->all(FLERR,"Compute ti tail when pair style does not " "compute tail corrections"); } else if (which[m] == KSPACE) { if (force->kspace == NULL) - error->all("Compute ti kspace style does not exist"); + error->all(FLERR,"Compute ti kspace style does not exist"); } } } @@ -148,7 +148,7 @@ double ComputeTI::compute_scalar() invoked_scalar = update->ntimestep; if (update->eflag_global != invoked_scalar) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); double dUdl = 0.0; diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp index 1f7d3ef655..c1cdc6d83d 100644 --- a/src/create_atoms.cpp +++ b/src/create_atoms.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; enum{BOX,REGION,SINGLE,RANDOM}; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {} @@ -46,17 +43,17 @@ CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {} void CreateAtoms::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Create_atoms command before simulation box is defined"); + error->all(FLERR,"Create_atoms command before simulation box is defined"); if (modify->nfix_restart_peratom) - error->all("Cannot create_atoms after " + error->all(FLERR,"Cannot create_atoms after " "reading restart file with per-atom info"); // parse arguments - if (narg < 2) error->all("Illegal create_atoms command"); + if (narg < 2) error->all(FLERR,"Illegal create_atoms command"); itype = atoi(arg[0]); if (itype <= 0 || itype > atom->ntypes) - error->all("Invalid atom type in create_atoms command"); + error->all(FLERR,"Invalid atom type in create_atoms command"); int iarg; if (strcmp(arg[1],"box") == 0) { @@ -64,29 +61,29 @@ void CreateAtoms::command(int narg, char **arg) iarg = 2; } else if (strcmp(arg[1],"region") == 0) { style = REGION; - if (narg < 3) error->all("Illegal create_atoms command"); + if (narg < 3) error->all(FLERR,"Illegal create_atoms command"); nregion = domain->find_region(arg[2]); - if (nregion == -1) error->all("Create_atoms region ID does not exist"); + if (nregion == -1) error->all(FLERR,"Create_atoms region ID does not exist"); iarg = 3;; } else if (strcmp(arg[1],"single") == 0) { style = SINGLE; - if (narg < 5) error->all("Illegal create_atoms command"); + if (narg < 5) error->all(FLERR,"Illegal create_atoms command"); xone[0] = atof(arg[2]); xone[1] = atof(arg[3]); xone[2] = atof(arg[4]); iarg = 5; } else if (strcmp(arg[1],"random") == 0) { style = RANDOM; - if (narg < 5) error->all("Illegal create_atoms command"); + if (narg < 5) error->all(FLERR,"Illegal create_atoms command"); nrandom = atoi(arg[2]); seed = atoi(arg[3]); if (strcmp(arg[4],"NULL") == 0) nregion = -1; else { nregion = domain->find_region(arg[4]); - if (nregion == -1) error->all("Create_atoms region ID does not exist"); + if (nregion == -1) error->all(FLERR,"Create_atoms region ID does not exist"); } iarg = 5; - } else error->all("Illegal create_atoms command"); + } else error->all(FLERR,"Illegal create_atoms command"); // process optional keywords @@ -100,30 +97,30 @@ void CreateAtoms::command(int narg, char **arg) while (iarg < narg) { if (strcmp(arg[iarg],"basis") == 0) { - if (iarg+3 > narg) error->all("Illegal create_atoms command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal create_atoms command"); if (domain->lattice == NULL) - error->all("Cannot create atoms with undefined lattice"); + error->all(FLERR,"Cannot create atoms with undefined lattice"); int ibasis = atoi(arg[iarg+1]); itype = atoi(arg[iarg+2]); if (ibasis <= 0 || ibasis > nbasis || itype <= 0 || itype > atom->ntypes) - error->all("Illegal create_atoms command"); + error->all(FLERR,"Illegal create_atoms command"); basistype[ibasis-1] = itype; iarg += 3; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal create_atoms command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal create_atoms command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal create_atoms command"); + else error->all(FLERR,"Illegal create_atoms command"); iarg += 2; - } else error->all("Illegal create_atoms command"); + } else error->all(FLERR,"Illegal create_atoms command"); } // error checks if (style == RANDOM) { - if (nrandom < 0) error->all("Illegal create_atoms command"); - if (seed <= 0) error->all("Illegal create_atoms command"); + if (nrandom < 0) error->all(FLERR,"Illegal create_atoms command"); + if (seed <= 0) error->all(FLERR,"Illegal create_atoms command"); } // demand lattice be defined @@ -134,10 +131,10 @@ void CreateAtoms::command(int narg, char **arg) if (style == BOX || style == REGION) { if (domain->lattice == NULL) - error->all("Cannot create atoms with undefined lattice"); + error->all(FLERR,"Cannot create atoms with undefined lattice"); } else if (scaleflag == 1) { if (domain->lattice == NULL) - error->all("Cannot create atoms with undefined lattice"); + error->all(FLERR,"Cannot create atoms with undefined lattice"); xone[0] *= domain->lattice->xlattice; xone[1] *= domain->lattice->ylattice; xone[2] *= domain->lattice->zlattice; @@ -171,7 +168,7 @@ void CreateAtoms::command(int narg, char **arg) bigint nblocal = atom->nlocal; MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world); if (atom->natoms < 0 || atom->natoms > MAXBIGINT) - error->all("Too many total atoms"); + error->all(FLERR,"Too many total atoms"); // print status diff --git a/src/create_box.cpp b/src/create_box.cpp index cc9ad9513e..7cdb033657 100644 --- a/src/create_box.cpp +++ b/src/create_box.cpp @@ -33,21 +33,21 @@ CreateBox::CreateBox(LAMMPS *lmp) : Pointers(lmp) {} void CreateBox::command(int narg, char **arg) { - if (narg != 2) error->all("Illegal create_box command"); + if (narg != 2) error->all(FLERR,"Illegal create_box command"); if (domain->box_exist) - error->all("Cannot create_box after simulation box is defined"); + error->all(FLERR,"Cannot create_box after simulation box is defined"); if (domain->dimension == 2 && domain->zperiodic == 0) - error->all("Cannot run 2d simulation with nonperiodic Z dimension"); + error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension"); domain->box_exist = 1; // region check int iregion = domain->find_region(arg[1]); - if (iregion == -1) error->all("Create_box region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Create_box region ID does not exist"); if (domain->regions[iregion]->bboxflag == 0) - error->all("Create_box region does not support a bounding box"); + error->all(FLERR,"Create_box region does not support a bounding box"); // if region not prism: // setup orthogonal domain diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 3de098fdab..9ed147e068 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ DeleteAtoms::DeleteAtoms(LAMMPS *lmp) : Pointers(lmp) {} @@ -43,10 +40,10 @@ DeleteAtoms::DeleteAtoms(LAMMPS *lmp) : Pointers(lmp) {} void DeleteAtoms::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Delete_atoms command before simulation box is defined"); - if (narg < 1) error->all("Illegal delete_atoms command"); + error->all(FLERR,"Delete_atoms command before simulation box is defined"); + if (narg < 1) error->all(FLERR,"Illegal delete_atoms command"); if (atom->tag_enable == 0) - error->all("Cannot use delete_atoms unless atoms have IDs"); + error->all(FLERR,"Cannot use delete_atoms unless atoms have IDs"); // store state before delete @@ -58,7 +55,7 @@ void DeleteAtoms::command(int narg, char **arg) else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg); else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg); else if (strcmp(arg[0],"porosity") == 0) delete_porosity(narg,arg); - else error->all("Illegal delete_atoms command"); + else error->all(FLERR,"Illegal delete_atoms command"); // delete local atoms flagged in dlist // reset nlocal @@ -121,10 +118,10 @@ void DeleteAtoms::command(int narg, char **arg) void DeleteAtoms::delete_group(int narg, char **arg) { - if (narg < 2) error->all("Illegal delete_atoms command"); + if (narg < 2) error->all(FLERR,"Illegal delete_atoms command"); int igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find delete_atoms group ID"); + if (igroup == -1) error->all(FLERR,"Could not find delete_atoms group ID"); options(narg-2,&arg[2]); // allocate and initialize deletion list @@ -146,10 +143,10 @@ void DeleteAtoms::delete_group(int narg, char **arg) void DeleteAtoms::delete_region(int narg, char **arg) { - if (narg < 2) error->all("Illegal delete_atoms command"); + if (narg < 2) error->all(FLERR,"Illegal delete_atoms command"); int iregion = domain->find_region(arg[1]); - if (iregion == -1) error->all("Could not find delete_atoms region ID"); + if (iregion == -1) error->all(FLERR,"Could not find delete_atoms region ID"); options(narg-2,&arg[2]); // allocate and initialize deletion list @@ -173,7 +170,7 @@ void DeleteAtoms::delete_region(int narg, char **arg) void DeleteAtoms::delete_overlap(int narg, char **arg) { - if (narg < 4) error->all("Illegal delete_atoms command"); + if (narg < 4) error->all(FLERR,"Illegal delete_atoms command"); // read args @@ -183,7 +180,7 @@ void DeleteAtoms::delete_overlap(int narg, char **arg) int igroup1 = group->find(arg[2]); int igroup2 = group->find(arg[3]); if (igroup1 < 0 || igroup2 < 0) - error->all("Could not find delete_atoms group ID"); + error->all(FLERR,"Could not find delete_atoms group ID"); options(narg-4,&arg[4]); int group1bit = group->bitmask[igroup1]; @@ -210,9 +207,9 @@ void DeleteAtoms::delete_overlap(int narg, char **arg) // if no pair style, neighbor list will be empty if (force->pair == NULL) - error->all("Delete_atoms requires a pair style be defined"); + error->all(FLERR,"Delete_atoms requires a pair style be defined"); if (cut > neighbor->cutneighmax) - error->all("Delete_atoms cutoff > neighbor cutoff"); + error->all(FLERR,"Delete_atoms cutoff > neighbor cutoff"); // setup domain, communication and neighboring // acquire ghosts @@ -319,10 +316,10 @@ void DeleteAtoms::delete_overlap(int narg, char **arg) void DeleteAtoms::delete_porosity(int narg, char **arg) { - if (narg < 4) error->all("Illegal delete_atoms command"); + if (narg < 4) error->all(FLERR,"Illegal delete_atoms command"); int iregion = domain->find_region(arg[1]); - if (iregion == -1) error->all("Could not find delete_atoms region ID"); + if (iregion == -1) error->all(FLERR,"Could not find delete_atoms region ID"); double porosity_fraction = atof(arg[2]); int seed = atoi(arg[3]); @@ -354,11 +351,11 @@ void DeleteAtoms::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"compress") == 0) { - if (iarg+2 > narg) error->all("Illegal delete_bonds command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal delete_bonds command"); if (strcmp(arg[iarg+1],"yes") == 0) compress_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) compress_flag = 0; - else error->all("Illegal delete_bonds command"); + else error->all(FLERR,"Illegal delete_bonds command"); iarg += 2; - } else error->all("Illegal delete_bonds command"); + } else error->all(FLERR,"Illegal delete_bonds command"); } } diff --git a/src/delete_bonds.cpp b/src/delete_bonds.cpp index 5bf219d975..01e1e3d14e 100644 --- a/src/delete_bonds.cpp +++ b/src/delete_bonds.cpp @@ -38,12 +38,12 @@ DeleteBonds::DeleteBonds(LAMMPS *lmp) : Pointers(lmp) {} void DeleteBonds::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Delete_bonds command before simulation box is defined"); + error->all(FLERR,"Delete_bonds command before simulation box is defined"); if (atom->natoms == 0) - error->all("Delete_bonds command with no atoms existing"); + error->all(FLERR,"Delete_bonds command with no atoms existing"); if (atom->molecular == 0) - error->all("Cannot use delete_bonds with non-molecular system"); - if (narg < 2) error->all("Illegal delete_bonds command"); + error->all(FLERR,"Cannot use delete_bonds with non-molecular system"); + if (narg < 2) error->all(FLERR,"Illegal delete_bonds command"); // init entire system since comm->borders is done // comm::init needs neighbor::init needs pair::init needs kspace::init, etc @@ -57,7 +57,7 @@ void DeleteBonds::command(int narg, char **arg) // identify group int igroup = group->find(arg[0]); - if (igroup == -1) error->all("Cannot find delete_bonds group ID"); + if (igroup == -1) error->all(FLERR,"Cannot find delete_bonds group ID"); int groupbit = group->bitmask[igroup]; // set style and which = type value @@ -70,12 +70,12 @@ void DeleteBonds::command(int narg, char **arg) else if (strcmp(arg[1],"dihedral") == 0) style = DIHEDRAL; else if (strcmp(arg[1],"improper") == 0) style = IMPROPER; else if (strcmp(arg[1],"stats") == 0) style = STATS; - else error->all("Illegal delete_bonds command"); + else error->all(FLERR,"Illegal delete_bonds command"); int iarg = 2; int which; if (style != MULTI && style != STATS) { - if (narg < 3) error->all("Illegal delete_bonds command"); + if (narg < 3) error->all(FLERR,"Illegal delete_bonds command"); which = atoi(arg[2]); iarg++; } @@ -90,7 +90,7 @@ void DeleteBonds::command(int narg, char **arg) if (strcmp(arg[iarg],"undo") == 0) undo_flag = 1; else if (strcmp(arg[iarg],"remove") == 0) remove_flag = 1; else if (strcmp(arg[iarg],"special") == 0) special_flag = 1; - else error->all("Illegal delete_bonds command"); + else error->all(FLERR,"Illegal delete_bonds command"); iarg++; } @@ -130,7 +130,7 @@ void DeleteBonds::command(int narg, char **arg) for (i = 0; i < nlocal; i++) { for (m = 0; m < num_bond[i]; m++) { atom1 = atom->map(atom->bond_atom[i][m]); - if (atom1 == -1) error->one("Bond atom missing in delete_bonds"); + if (atom1 == -1) error->one(FLERR,"Bond atom missing in delete_bonds"); if (mask[i] & groupbit && mask[atom1] & groupbit) { flag = 0; if (style == MULTI) flag = 1; @@ -158,7 +158,7 @@ void DeleteBonds::command(int narg, char **arg) atom2 = atom->map(atom->angle_atom2[i][m]); atom3 = atom->map(atom->angle_atom3[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1) - error->one("Angle atom missing in delete_bonds"); + error->one(FLERR,"Angle atom missing in delete_bonds"); if (mask[atom1] & groupbit && mask[atom2] & groupbit && mask[atom3] & groupbit) { flag = 0; @@ -189,7 +189,7 @@ void DeleteBonds::command(int narg, char **arg) atom3 = atom->map(atom->dihedral_atom3[i][m]); atom4 = atom->map(atom->dihedral_atom4[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) - error->one("Dihedral atom missing in delete_bonds"); + error->one(FLERR,"Dihedral atom missing in delete_bonds"); if (mask[atom1] & groupbit && mask[atom2] & groupbit && mask[atom3] & groupbit && mask[atom4] & groupbit) { flag = 0; @@ -220,7 +220,7 @@ void DeleteBonds::command(int narg, char **arg) atom3 = atom->map(atom->improper_atom3[i][m]); atom4 = atom->map(atom->improper_atom4[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) - error->one("Improper atom missing in delete_bonds"); + error->one(FLERR,"Improper atom missing in delete_bonds"); if (mask[atom1] & groupbit && mask[atom2] & groupbit && mask[atom3] & groupbit && mask[atom4] & groupbit) { flag = 0; diff --git a/src/dihedral.cpp b/src/dihedral.cpp index 1a3f6f5a45..a3edadc0c0 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -53,9 +53,9 @@ Dihedral::~Dihedral() void Dihedral::init() { - if (!allocated) error->all("Dihedral coeffs are not set"); + if (!allocated) error->all(FLERR,"Dihedral coeffs are not set"); for (int i = 1; i <= atom->ndihedraltypes; i++) - if (setflag[i] == 0) error->all("All dihedral coeffs are not set"); + if (setflag[i] == 0) error->all(FLERR,"All dihedral coeffs are not set"); init_style(); } diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp index f433541d9e..1793a5e195 100644 --- a/src/displace_atoms.cpp +++ b/src/displace_atoms.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; enum{MOVE,RAMP,RANDOM}; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ DisplaceAtoms::DisplaceAtoms(LAMMPS *lmp) : Pointers(lmp) {} @@ -44,10 +41,10 @@ void DisplaceAtoms::command(int narg, char **arg) int i; if (domain->box_exist == 0) - error->all("Displace_atoms command before simulation box is defined"); - if (narg < 2) error->all("Illegal displace_atoms command"); + error->all(FLERR,"Displace_atoms command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal displace_atoms command"); if (modify->nfix_restart_peratom) - error->all("Cannot displace_atoms after " + error->all(FLERR,"Cannot displace_atoms after " "reading restart file with per-atom info"); if (comm->me == 0 && screen) fprintf(screen,"Displacing atoms ...\n"); @@ -55,14 +52,14 @@ void DisplaceAtoms::command(int narg, char **arg) // group and style int igroup = group->find(arg[0]); - if (igroup == -1) error->all("Could not find displace_atoms group ID"); + if (igroup == -1) error->all(FLERR,"Could not find displace_atoms group ID"); int groupbit = group->bitmask[igroup]; int style; if (strcmp(arg[1],"move") == 0) style = MOVE; else if (strcmp(arg[1],"ramp") == 0) style = RAMP; else if (strcmp(arg[1],"random") == 0) style = RANDOM; - else error->all("Illegal displace_atoms command"); + else error->all(FLERR,"Illegal displace_atoms command"); // set option defaults @@ -77,7 +74,7 @@ void DisplaceAtoms::command(int narg, char **arg) // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of displace_atoms with undefined lattice"); + error->all(FLERR,"Use of displace_atoms with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -116,7 +113,7 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[2],"x") == 0) d_dim = 0; else if (strcmp(arg[2],"y") == 0) d_dim = 1; else if (strcmp(arg[2],"z") == 0) d_dim = 2; - else error->all("Illegal displace_atoms ramp command"); + else error->all(FLERR,"Illegal displace_atoms ramp command"); double d_lo,d_hi; if (d_dim == 0) { @@ -134,7 +131,7 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[5],"x") == 0) coord_dim = 0; else if (strcmp(arg[5],"y") == 0) coord_dim = 1; else if (strcmp(arg[5],"z") == 0) coord_dim = 2; - else error->all("Illegal displace_atoms ramp command"); + else error->all(FLERR,"Illegal displace_atoms ramp command"); double coord_lo,coord_hi; if (coord_dim == 0) { @@ -175,7 +172,7 @@ void DisplaceAtoms::command(int narg, char **arg) double dy = yscale*atof(arg[3]); double dz = zscale*atof(arg[4]); int seed = atoi(arg[5]); - if (seed <= 0) error->all("Illegal displace_atoms random command"); + if (seed <= 0) error->all(FLERR,"Illegal displace_atoms random command"); double **x = atom->x; int *mask = atom->mask; @@ -218,7 +215,7 @@ void DisplaceAtoms::command(int narg, char **arg) char str[128]; sprintf(str,"Lost atoms via displace_atoms: original " BIGINT_FORMAT " current " BIGINT_FORMAT,atom->natoms,natoms); - error->all(str); + error->all(FLERR,str); } } @@ -228,16 +225,16 @@ void DisplaceAtoms::command(int narg, char **arg) void DisplaceAtoms::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal displace_atoms command"); + if (narg < 0) error->all(FLERR,"Illegal displace_atoms command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal displace_atoms command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal displace_atoms command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal displace_atoms command"); + else error->all(FLERR,"Illegal displace_atoms command"); iarg += 2; - } else error->all("Illegal displace_atoms command"); + } else error->all(FLERR,"Illegal displace_atoms command"); } } diff --git a/src/displace_box.cpp b/src/displace_box.cpp index f2e3363a6d..79f8865788 100644 --- a/src/displace_box.cpp +++ b/src/displace_box.cpp @@ -43,10 +43,10 @@ void DisplaceBox::command(int narg, char **arg) int i; if (domain->box_exist == 0) - error->all("Displace_box command before simulation box is defined"); - if (narg < 2) error->all("Illegal displace_box command"); + error->all(FLERR,"Displace_box command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal displace_box command"); if (modify->nfix_restart_peratom) - error->all("Cannot displace_box after " + error->all(FLERR,"Cannot displace_box after " "reading restart file with per-atom info"); if (comm->me == 0 && screen) fprintf(screen,"Displacing box ...\n"); @@ -54,7 +54,7 @@ void DisplaceBox::command(int narg, char **arg) // group int igroup = group->find(arg[0]); - if (igroup == -1) error->all("Could not find displace_box group ID"); + if (igroup == -1) error->all(FLERR,"Could not find displace_box group ID"); int groupbit = group->bitmask[igroup]; // set defaults @@ -76,48 +76,48 @@ void DisplaceBox::command(int narg, char **arg) else if (strcmp(arg[iarg],"y") == 0) index = 1; else if (strcmp(arg[iarg],"z") == 0) index = 2; - if (iarg+2 > narg) error->all("Illegal displace_box command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal displace_box command"); if (strcmp(arg[iarg+1],"final") == 0) { - if (iarg+4 > narg) error->all("Illegal displace_box command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal displace_box command"); set[index].style = FINAL; set[index].flo = atof(arg[iarg+2]); set[index].fhi = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg+1],"delta") == 0) { - if (iarg+4 > narg) error->all("Illegal displace_box command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal displace_box command"); set[index].style = DELTA; set[index].dlo = atof(arg[iarg+2]); set[index].dhi = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg+1],"scale") == 0) { - if (iarg+3 > narg) error->all("Illegal displace_box command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal displace_box command"); set[index].style = SCALE; set[index].scale = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"volume") == 0) { set[index].style = VOLUME; iarg += 2; - } else error->all("Illegal displace_box command"); + } else error->all(FLERR,"Illegal displace_box command"); } else if (strcmp(arg[iarg],"xy") == 0 || strcmp(arg[iarg],"xz") == 0 || strcmp(arg[iarg],"yz") == 0) { if (triclinic == 0) - error->all("Displace_box tilt factors require triclinic box"); + error->all(FLERR,"Displace_box tilt factors require triclinic box"); if (strcmp(arg[iarg],"xy") == 0) index = 5; else if (strcmp(arg[iarg],"xz") == 0) index = 4; else if (strcmp(arg[iarg],"yz") == 0) index = 3; - if (iarg+2 > narg) error->all("Illegal displace_box command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal displace_box command"); if (strcmp(arg[iarg+1],"final") == 0) { - if (iarg+3 > narg) error->all("Illegal displace_box command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal displace_box command"); set[index].style = FINAL; set[index].ftilt = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"delta") == 0) { - if (iarg+3 > narg) error->all("Illegal displace_box command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal displace_box command"); set[index].style = DELTA; set[index].dtilt = atof(arg[iarg+2]); iarg += 3; - } else error->all("Illegal displace_box command"); + } else error->all(FLERR,"Illegal displace_box command"); } else break; } @@ -131,14 +131,14 @@ void DisplaceBox::command(int narg, char **arg) if ((set[0].style && domain->xperiodic == 0) || (set[1].style && domain->yperiodic == 0) || (set[2].style && domain->zperiodic == 0)) - error->all("Cannot displace_box on a non-periodic boundary"); + error->all(FLERR,"Cannot displace_box on a non-periodic boundary"); if (set[3].style && (domain->yperiodic == 0 || domain->zperiodic == 0)) - error->all("Cannot displace_box on a non-periodic boundary"); + error->all(FLERR,"Cannot displace_box on a non-periodic boundary"); if (set[4].style && (domain->xperiodic == 0 || domain->zperiodic == 0)) - error->all("Cannot displace_box on a non-periodic boundary"); + error->all(FLERR,"Cannot displace_box on a non-periodic boundary"); if (set[5].style && (domain->xperiodic == 0 || domain->yperiodic == 0)) - error->all("Cannot displace_box on a non-periodic boundary"); + error->all(FLERR,"Cannot displace_box on a non-periodic boundary"); // apply scaling to FINAL,DELTA since they have distance units @@ -147,7 +147,7 @@ void DisplaceBox::command(int narg, char **arg) if (set[i].style == FINAL || set[i].style == DELTA) flag = 1; if (flag && scaleflag && domain->lattice == NULL) - error->all("Use of displace_box with undefined lattice"); + error->all(FLERR,"Use of displace_box with undefined lattice"); double xscale,yscale,zscale; if (flag && scaleflag) { @@ -224,25 +224,25 @@ void DisplaceBox::command(int narg, char **arg) if (set[other1].style == NONE) { if (set[other2].style == NONE || set[other2].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = ONE_FROM_ONE; set[i].fixed = other1; set[i].dynamic1 = other2; } else if (set[other2].style == NONE) { if (set[other1].style == NONE || set[other1].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = ONE_FROM_ONE; set[i].fixed = other2; set[i].dynamic1 = other1; } else if (set[other1].style == VOLUME) { if (set[other2].style == NONE || set[other2].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = TWO_FROM_ONE; set[i].fixed = other1; set[i].dynamic1 = other2; } else if (set[other2].style == VOLUME) { if (set[other1].style == NONE || set[other1].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = TWO_FROM_ONE; set[i].fixed = other2; set[i].dynamic1 = other1; @@ -310,7 +310,7 @@ void DisplaceBox::command(int narg, char **arg) if (set[3].tilt_stop < -0.5*yprd_stop || set[3].tilt_stop > 0.5*yprd_stop || set[4].tilt_stop < -0.5*xprd_stop || set[4].tilt_stop > 0.5*xprd_stop || set[5].tilt_stop < -0.5*xprd_stop || set[5].tilt_stop > 0.5*xprd_stop) - error->all("Induced tilt by displace_box is too large"); + error->all(FLERR,"Induced tilt by displace_box is too large"); // convert atoms to lamda coords @@ -384,7 +384,7 @@ void DisplaceBox::command(int narg, char **arg) char str[128]; sprintf(str,"Lost atoms via displace_box: original " BIGINT_FORMAT " current " BIGINT_FORMAT,atom->natoms,natoms); - error->all(str); + error->all(FLERR,str); } } @@ -394,7 +394,7 @@ void DisplaceBox::command(int narg, char **arg) void DisplaceBox::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal displace_box command"); + if (narg < 0) error->all(FLERR,"Illegal displace_box command"); remapflag = X_REMAP; scaleflag = 1; @@ -402,17 +402,17 @@ void DisplaceBox::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"remap") == 0) { - if (iarg+2 > narg) error->all("Illegal displace_box command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal displace_box command"); if (strcmp(arg[iarg+1],"x") == 0) remapflag = X_REMAP; else if (strcmp(arg[iarg+1],"none") == 0) remapflag = NO_REMAP; - else error->all("Illegal displace_box command"); + else error->all(FLERR,"Illegal displace_box command"); iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal displace_box command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal displace_box command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal displace_box command"); + else error->all(FLERR,"Illegal displace_box command"); iarg += 2; - } else error->all("Illegal displace_box command"); + } else error->all(FLERR,"Illegal displace_box command"); } } diff --git a/src/domain.cpp b/src/domain.cpp index 4688a733f1..a1a0045fa9 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -39,8 +39,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 #define SMALL 1.0e-4 #define DELTA 1 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp @@ -132,24 +130,24 @@ void Domain::set_initial_box() // error checks for orthogonal and triclinic domains if (boxlo[0] >= boxhi[0] || boxlo[1] >= boxhi[1] || boxlo[2] >= boxhi[2]) - error->one("Box bounds are invalid"); + error->one(FLERR,"Box bounds are invalid"); if (triclinic) { if (domain->dimension == 2 && (xz != 0.0 || yz != 0.0)) - error->all("Cannot skew triclinic box in z for 2d simulation"); + error->all(FLERR,"Cannot skew triclinic box in z for 2d simulation"); if (xy != 0.0 && (!xperiodic || !yperiodic)) - error->all("Triclinic box must be periodic in skewed dimensions"); + error->all(FLERR,"Triclinic box must be periodic in skewed dimensions"); if (xz != 0.0 && (!xperiodic || !zperiodic)) - error->all("Triclinic box must be periodic in skewed dimensions"); + error->all(FLERR,"Triclinic box must be periodic in skewed dimensions"); if (yz != 0.0 && (!yperiodic || !zperiodic)) - error->all("Triclinic box must be periodic in skewed dimensions"); + error->all(FLERR,"Triclinic box must be periodic in skewed dimensions"); if (fabs(xy/(boxhi[0]-boxlo[0])) > 0.5) - error->all("Triclinic box skew is too large"); + error->all(FLERR,"Triclinic box skew is too large"); if (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5) - error->all("Triclinic box skew is too large"); + error->all(FLERR,"Triclinic box skew is too large"); if (fabs(yz/(boxhi[1]-boxlo[1])) > 0.5) - error->all("Triclinic box skew is too large"); + error->all(FLERR,"Triclinic box skew is too large"); } // adjust box lo/hi for shrink-wrapped dims @@ -319,21 +317,21 @@ void Domain::reset_box() else if (boundary[0][0] == 3) boxlo[0] = MIN(-all[0][0]-SMALL,minxlo); if (boundary[0][1] == 2) boxhi[0] = all[0][1] + SMALL; else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+SMALL,minxhi); - if (boxlo[0] > boxhi[0]) error->all("Illegal simulation box"); + if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box"); } if (yperiodic == 0) { if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - SMALL; else if (boundary[1][0] == 3) boxlo[1] = MIN(-all[1][0]-SMALL,minylo); if (boundary[1][1] == 2) boxhi[1] = all[1][1] + SMALL; else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+SMALL,minyhi); - if (boxlo[1] > boxhi[1]) error->all("Illegal simulation box"); + if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box"); } if (zperiodic == 0) { if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - SMALL; else if (boundary[2][0] == 3) boxlo[2] = MIN(-all[2][0]-SMALL,minzlo); if (boundary[2][1] == 2) boxhi[2] = all[2][1] + SMALL; else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+SMALL,minzhi); - if (boxlo[2] > boxhi[2]) error->all("Illegal simulation box"); + if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box"); } } @@ -992,14 +990,14 @@ void Domain::set_lattice(int narg, char **arg) void Domain::add_region(int narg, char **arg) { - if (narg < 2) error->all("Illegal region command"); + if (narg < 2) error->all(FLERR,"Illegal region command"); if (strcmp(arg[1],"delete") == 0) { delete_region(narg,arg); return; } - if (find_region(arg[0]) >= 0) error->all("Reuse of region ID"); + if (find_region(arg[0]) >= 0) error->all(FLERR,"Reuse of region ID"); // extend Region list if necessary @@ -1011,7 +1009,7 @@ void Domain::add_region(int narg, char **arg) // create the Region - if (strcmp(arg[1],"none") == 0) error->all("Invalid region style"); + if (strcmp(arg[1],"none") == 0) error->all(FLERR,"Invalid region style"); #define REGION_CLASS #define RegionStyle(key,Class) \ @@ -1020,7 +1018,7 @@ void Domain::add_region(int narg, char **arg) #include "style_region.h" #undef REGION_CLASS - else error->all("Invalid region style"); + else error->all(FLERR,"Invalid region style"); nregion++; } @@ -1031,10 +1029,10 @@ void Domain::add_region(int narg, char **arg) void Domain::delete_region(int narg, char **arg) { - if (narg != 2) error->all("Illegal region command"); + if (narg != 2) error->all(FLERR,"Illegal region command"); int iregion = find_region(arg[0]); - if (iregion == -1) error->all("Delete region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Delete region ID does not exist"); delete regions[iregion]; regions[iregion] = regions[nregion-1]; @@ -1059,7 +1057,7 @@ int Domain::find_region(char *name) void Domain::set_boundary(int narg, char **arg) { - if (narg != 3) error->all("Illegal boundary command"); + if (narg != 3) error->all(FLERR,"Illegal boundary command"); char c; for (int idim = 0; idim < 3; idim++) @@ -1072,13 +1070,13 @@ void Domain::set_boundary(int narg, char **arg) else if (c == 'f') boundary[idim][iside] = 1; else if (c == 's') boundary[idim][iside] = 2; else if (c == 'm') boundary[idim][iside] = 3; - else error->all("Illegal boundary command"); + else error->all(FLERR,"Illegal boundary command"); } for (int idim = 0; idim < 3; idim++) if ((boundary[idim][0] == 0 && boundary[idim][1]) || (boundary[idim][0] && boundary[idim][1] == 0)) - error->all("Both sides of boundary must be periodic"); + error->all(FLERR,"Both sides of boundary must be periodic"); if (boundary[0][0] == 0) xperiodic = 1; else xperiodic = 0; diff --git a/src/dump.cpp b/src/dump.cpp index 2dd5106bf5..feda8ea156 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -36,9 +36,6 @@ Dump *Dump::dumpptr; #define IBIG 2147483647 #define EPSILON 1.0e-6 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{ASCEND,DESCEND}; /* ---------------------------------------------------------------------- */ @@ -170,14 +167,14 @@ void Dump::init() if (sort_flag) { if (sortcol == 0 && atom->tag_enable == 0) - error->all("Cannot dump sort on atom IDs with no atom IDs defined"); + error->all(FLERR,"Cannot dump sort on atom IDs with no atom IDs defined"); if (sortcol && sortcol > size_one) - error->all("Dump sort column is invalid"); + error->all(FLERR,"Dump sort column is invalid"); if (nprocs > 1 && irregular == NULL) irregular = new Irregular(lmp); bigint size = group->count(igroup); - if (size > MAXSMALLINT) error->all("Too many atoms to dump sort"); + if (size > MAXSMALLINT) error->all(FLERR,"Too many atoms to dump sort"); // set reorderflag = 1 if can simply reorder local atoms rather than sort // criteria: sorting by ID, atom IDs are consecutive from 1 to Natoms @@ -281,7 +278,7 @@ void Dump::write() if (nmax > maxbuf) { if ((bigint) nmax * size_one > MAXSMALLINT) - error->all("Too much per-proc info for dump"); + error->all(FLERR,"Too much per-proc info for dump"); maxbuf = nmax; memory->destroy(buf); memory->create(buf,maxbuf*size_one,"dump:buf"); @@ -382,7 +379,7 @@ void Dump::openfile() sprintf(gzip,"gzip -6 > %s",filecurrent); fp = popen(gzip,"w"); #else - error->one("Cannot open gzipped file"); + error->one(FLERR,"Cannot open gzipped file"); #endif } else if (binary) { fp = fopen(filecurrent,"wb"); @@ -392,7 +389,7 @@ void Dump::openfile() fp = fopen(filecurrent,"w"); } - if (fp == NULL) error->one("Cannot open dump file"); + if (fp == NULL) error->one(FLERR,"Cannot open dump file"); } else fp = NULL; // delete string with timestep replaced @@ -622,18 +619,18 @@ int Dump::bufcompare_reverse(const void *pi, const void *pj) void Dump::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal dump_modify command"); + if (narg == 0) error->all(FLERR,"Illegal dump_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"append") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) append_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) append_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"every") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); int idump; for (idump = 0; idump < output->ndump; idump++) if (strcmp(id,output->dump[idump]->id) == 0) break; @@ -646,24 +643,24 @@ void Dump::modify_params(int narg, char **arg) n = 0; } else { n = atoi(arg[iarg+1]); - if (n <= 0) error->all("Illegal dump_modify command"); + if (n <= 0) error->all(FLERR,"Illegal dump_modify command"); } output->every_dump[idump] = n; iarg += 2; } else if (strcmp(arg[iarg],"first") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) first_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) first_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"flush") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) flush_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) flush_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"format") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); delete [] format_user; format_user = NULL; if (strcmp(arg[iarg+1],"none")) { @@ -673,12 +670,12 @@ void Dump::modify_params(int narg, char **arg) } iarg += 2; } else if (strcmp(arg[iarg],"pad") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); padflag = atoi(arg[iarg+1]); - if (padflag < 0) error->all("Illegal dump_modify command"); + if (padflag < 0) error->all(FLERR,"Illegal dump_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"sort") == 0) { - if (iarg+2 > narg) error->all("Illegal dump_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"off") == 0) sort_flag = 0; else if (strcmp(arg[iarg+1],"id") == 0) { sort_flag = 1; @@ -688,7 +685,7 @@ void Dump::modify_params(int narg, char **arg) sort_flag = 1; sortcol = atoi(arg[iarg+1]); sortorder = ASCEND; - if (sortcol == 0) error->all("Illegal dump_modify command"); + if (sortcol == 0) error->all(FLERR,"Illegal dump_modify command"); if (sortcol < 0) { sortorder = DESCEND; sortcol = -sortcol; @@ -698,7 +695,7 @@ void Dump::modify_params(int narg, char **arg) iarg += 2; } else { int n = modify_param(narg-iarg,&arg[iarg]); - if (n == 0) error->all("Illegal dump_modify command"); + if (n == 0) error->all(FLERR,"Illegal dump_modify command"); iarg += n; } } diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp index 513e6baef5..2365fb3e2e 100644 --- a/src/dump_atom.cpp +++ b/src/dump_atom.cpp @@ -25,7 +25,7 @@ using namespace LAMMPS_NS; DumpAtom::DumpAtom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg != 5) error->all("Illegal dump atom command"); + if (narg != 5) error->all(FLERR,"Illegal dump atom command"); scale_flag = 1; image_flag = 0; @@ -120,16 +120,16 @@ void DumpAtom::init_style() int DumpAtom::modify_param(int narg, char **arg) { if (strcmp(arg[0],"scale") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"yes") == 0) scale_flag = 1; else if (strcmp(arg[1],"no") == 0) scale_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); return 2; } else if (strcmp(arg[0],"image") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"yes") == 0) image_flag = 1; else if (strcmp(arg[1],"no") == 0) image_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); return 2; } return 0; diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp index eb1732e93f..940e34549f 100755 --- a/src/dump_cfg.cpp +++ b/src/dump_cfg.cpp @@ -46,15 +46,15 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) : (strcmp(arg[7],"xs") != 0 && strcmp(arg[7],"xsu") != 0) || (strcmp(arg[8],"ys") != 0 && strcmp(arg[8],"ysu") != 0) || (strcmp(arg[9],"zs") != 0 && strcmp(arg[9],"zsu") != 0)) - error->all("Dump cfg arguments must start with " + error->all(FLERR,"Dump cfg arguments must start with " "'id type xs ys zs' or 'id type xsu ysu zsu'"); if (strcmp(arg[7],"xs") == 0) if (strcmp(arg[8],"ysu") == 0 || strcmp(arg[9],"zsu") == 0) - error->all("Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); + error->all(FLERR,"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); else unwrapflag = 0; else if (strcmp(arg[8],"ys") == 0 || strcmp(arg[9],"zs") == 0) - error->all("Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); + error->all(FLERR,"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); else unwrapflag = 1; // arrays for data rearrangement @@ -80,7 +80,7 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid keyword in dump cfg command"); + error->all(FLERR,"Invalid keyword in dump cfg command"); *ptr = '\0'; *(ptr+2) = '\0'; auxname[i] = new char[strlen(suffix) + 3]; @@ -117,7 +117,7 @@ DumpCFG::~DumpCFG() void DumpCFG::init_style() { - if (multifile == 0) error->all("Dump cfg requires one snapshot per file"); + if (multifile == 0) error->all(FLERR,"Dump cfg requires one snapshot per file"); DumpCustom::init_style(); } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 5a3a46b967..7382ec084c 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -53,7 +53,7 @@ enum{INT,DOUBLE,STRING}; DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg == 5) error->all("No dump custom arguments specified"); + if (narg == 5) error->all(FLERR,"No dump custom arguments specified"); clearstep = 1; @@ -97,7 +97,7 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : ioptional = parse_fields(narg,arg); if (ioptional < narg && strcmp(style,"image") != 0) - error->all("Invalid attribute in dump custom command"); + error->all(FLERR,"Invalid attribute in dump custom command"); size_one = nfield = ioptional - 5; // atom selection arrays @@ -250,23 +250,23 @@ void DumpCustom::init_style() int icompute; for (int i = 0; i < ncompute; i++) { icompute = modify->find_compute(id_compute[i]); - if (icompute < 0) error->all("Could not find dump custom compute ID"); + if (icompute < 0) error->all(FLERR,"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"); + if (ifix < 0) error->all(FLERR,"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"); + error->all(FLERR,"Dump custom and fix not computed at compatible times"); } int ivariable; for (int i = 0; i < nvariable; i++) { ivariable = input->variable->find(id_variable[i]); - if (ivariable < 0) error->all("Could not find dump custom variable name"); + if (ivariable < 0) error->all(FLERR,"Could not find dump custom variable name"); variable[i] = ivariable; } @@ -274,7 +274,7 @@ void DumpCustom::init_style() if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for dump custom does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for dump custom does not exist"); } // open single file, one time only @@ -448,7 +448,7 @@ int DumpCustom::count() nstride = 1; } else if (thresh_array[ithresh] == MOL) { if (!atom->molecule_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); int *molecule = atom->molecule; for (i = 0; i < nlocal; i++) dchoose[i] = molecule[i]; ptr = dchoose; @@ -704,108 +704,108 @@ int DumpCustom::count() } else if (thresh_array[ithresh] == Q) { if (!atom->q_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = atom->q; nstride = 1; } else if (thresh_array[ithresh] == MUX) { if (!atom->mu_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->mu[0][0]; nstride = 4; } else if (thresh_array[ithresh] == MUY) { if (!atom->mu_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->mu[0][1]; nstride = 4; } else if (thresh_array[ithresh] == MUZ) { if (!atom->mu_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->mu[0][2]; nstride = 4; } else if (thresh_array[ithresh] == MU) { if (!atom->mu_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->mu[0][3]; nstride = 4; } else if (thresh_array[ithresh] == RADIUS) { if (!atom->radius_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = atom->radius; nstride = 1; } else if (thresh_array[ithresh] == DIAMETER) { if (!atom->radius_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); double *radius = atom->radius; for (i = 0; i < nlocal; i++) dchoose[i] = 2.0*radius[i]; ptr = dchoose; nstride = 1; } else if (thresh_array[ithresh] == OMEGAX) { if (!atom->omega_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->omega[0][0]; nstride = 3; } else if (thresh_array[ithresh] == OMEGAY) { if (!atom->omega_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->omega[0][1]; nstride = 3; } else if (thresh_array[ithresh] == OMEGAZ) { if (!atom->omega_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->omega[0][2]; nstride = 3; } else if (thresh_array[ithresh] == ANGMOMX) { if (!atom->angmom_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->angmom[0][0]; nstride = 3; } else if (thresh_array[ithresh] == ANGMOMY) { if (!atom->angmom_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->angmom[0][1]; nstride = 3; } else if (thresh_array[ithresh] == ANGMOMZ) { if (!atom->angmom_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->angmom[0][2]; nstride = 3; } else if (thresh_array[ithresh] == TQX) { if (!atom->torque_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->torque[0][0]; nstride = 3; } else if (thresh_array[ithresh] == TQY) { if (!atom->torque_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->torque[0][1]; nstride = 3; } else if (thresh_array[ithresh] == TQZ) { if (!atom->torque_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = &atom->torque[0][2]; nstride = 3; } else if (thresh_array[ithresh] == SPIN) { if (!atom->spin_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); int *spin = atom->spin; for (i = 0; i < nlocal; i++) dchoose[i] = spin[i]; ptr = dchoose; nstride = 1; } else if (thresh_array[ithresh] == ERADIUS) { if (!atom->eradius_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = atom->eradius; nstride = 1; } else if (thresh_array[ithresh] == ERVEL) { if (!atom->ervel_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = atom->ervel; nstride = 1; } else if (thresh_array[ithresh] == ERFORCE) { if (!atom->erforce_flag) - error->all("Threshhold for an atom property that isn't allocated"); + error->all(FLERR,"Threshhold for an atom property that isn't allocated"); ptr = atom->erforce; nstride = 1; @@ -934,7 +934,7 @@ int DumpCustom::parse_fields(int narg, char **arg) vtype[i] = INT; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_molecule; vtype[i] = INT; } else if (strcmp(arg[iarg],"type") == 0) { @@ -1023,104 +1023,104 @@ int DumpCustom::parse_fields(int narg, char **arg) } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_q; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_mux; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_muy; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_muz; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_mu; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_radius; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_diameter; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_omegax; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_omegay; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_omegaz; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_angmomx; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_angmomy; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_angmomz; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_tqx; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_tqy; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all("Dumping an atom property that isn't allocated"); + error->all(FLERR,"Dumping an atom property that isn't allocated"); pack_choice[i] = &DumpCustom::pack_tqz; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"spin") == 0) { if (!atom->spin_flag) - error->all("Dumping an atom quantity that isn't allocated"); + error->all(FLERR,"Dumping an atom quantity that isn't allocated"); pack_choice[i] = &DumpCustom::pack_spin; vtype[i] = INT; } else if (strcmp(arg[iarg],"eradius") == 0) { if (!atom->eradius_flag) - error->all("Dumping an atom quantity that isn't allocated"); + error->all(FLERR,"Dumping an atom quantity that isn't allocated"); pack_choice[i] = &DumpCustom::pack_eradius; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"ervel") == 0) { if (!atom->ervel_flag) - error->all("Dumping an atom quantity that isn't allocated"); + error->all(FLERR,"Dumping an atom quantity that isn't allocated"); pack_choice[i] = &DumpCustom::pack_ervel; vtype[i] = DOUBLE; } else if (strcmp(arg[iarg],"erforce") == 0) { if (!atom->erforce_flag) - error->all("Dumping an atom quantity that isn't allocated"); + error->all(FLERR,"Dumping an atom quantity that isn't allocated"); pack_choice[i] = &DumpCustom::pack_erforce; vtype[i] = DOUBLE; @@ -1138,22 +1138,22 @@ int DumpCustom::parse_fields(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump custom command"); + error->all(FLERR,"Invalid attribute in dump custom command"); argindex[i] = atoi(ptr+1); *ptr = '\0'; } else argindex[i] = 0; n = modify->find_compute(suffix); - if (n < 0) error->all("Could not find dump custom compute ID"); + if (n < 0) error->all(FLERR,"Could not find dump custom compute ID"); if (modify->compute[n]->peratom_flag == 0) - error->all("Dump custom compute does not compute per-atom info"); + error->all(FLERR,"Dump custom compute does not compute per-atom info"); if (argindex[i] == 0 && modify->compute[n]->size_peratom_cols > 0) - error->all("Dump custom compute does not calculate per-atom vector"); + error->all(FLERR,"Dump custom compute does not calculate per-atom vector"); if (argindex[i] > 0 && modify->compute[n]->size_peratom_cols == 0) - error->all("Dump custom compute does not calculate per-atom array"); + error->all(FLERR,"Dump custom compute does not calculate per-atom array"); if (argindex[i] > 0 && argindex[i] > modify->compute[n]->size_peratom_cols) - error->all("Dump custom compute vector is accessed out-of-range"); + error->all(FLERR,"Dump custom compute vector is accessed out-of-range"); field2index[i] = add_compute(suffix); delete [] suffix; @@ -1172,22 +1172,22 @@ int DumpCustom::parse_fields(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump custom command"); + error->all(FLERR,"Invalid attribute in dump custom command"); argindex[i] = atoi(ptr+1); *ptr = '\0'; } else argindex[i] = 0; n = modify->find_fix(suffix); - if (n < 0) error->all("Could not find dump custom fix ID"); + if (n < 0) error->all(FLERR,"Could not find dump custom fix ID"); if (modify->fix[n]->peratom_flag == 0) - error->all("Dump custom fix does not compute per-atom info"); + error->all(FLERR,"Dump custom fix does not compute per-atom info"); if (argindex[i] == 0 && modify->fix[n]->size_peratom_cols > 0) - error->all("Dump custom fix does not compute per-atom vector"); + error->all(FLERR,"Dump custom fix does not compute per-atom vector"); if (argindex[i] > 0 && modify->fix[n]->size_peratom_cols == 0) - error->all("Dump custom fix does not compute per-atom array"); + error->all(FLERR,"Dump custom fix does not compute per-atom array"); if (argindex[i] > 0 && argindex[i] > modify->fix[n]->size_peratom_cols) - error->all("Dump custom fix vector is accessed out-of-range"); + error->all(FLERR,"Dump custom fix vector is accessed out-of-range"); field2index[i] = add_fix(suffix); delete [] suffix; @@ -1205,9 +1205,9 @@ int DumpCustom::parse_fields(int narg, char **arg) argindex[i] = 0; n = input->variable->find(suffix); - if (n < 0) error->all("Could not find dump custom variable name"); + if (n < 0) error->all(FLERR,"Could not find dump custom variable name"); if (input->variable->atomstyle(n) == 0) - error->all("Dump custom variable is not atom-style variable"); + error->all(FLERR,"Dump custom variable is not atom-style variable"); field2index[i] = add_variable(suffix); delete [] suffix; @@ -1302,11 +1302,11 @@ int DumpCustom::add_variable(char *id) int DumpCustom::modify_param(int narg, char **arg) { if (strcmp(arg[0],"region") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"none") == 0) iregion = -1; else { iregion = domain->find_region(arg[1]); - if (iregion == -1) error->all("Dump_modify region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Dump_modify region ID does not exist"); int n = strlen(arg[1]) + 1; idregion = new char[n]; strcpy(idregion,arg[1]); @@ -1315,7 +1315,7 @@ int DumpCustom::modify_param(int narg, char **arg) } else if (strcmp(arg[0],"element") == 0) { if (narg < ntypes+1) - error->all("Dump modify element names do not match atom types"); + error->all(FLERR,"Dump modify element names do not match atom types"); if (typenames) { for (int i = 1; i <= ntypes; i++) delete [] typenames[i]; @@ -1332,7 +1332,7 @@ int DumpCustom::modify_param(int narg, char **arg) return ntypes+1; } else if (strcmp(arg[0],"thresh") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"none") == 0) { if (nthresh) { memory->destroy(thresh_array); @@ -1346,7 +1346,7 @@ int DumpCustom::modify_param(int narg, char **arg) return 2; } - if (narg < 4) error->all("Illegal dump_modify command"); + if (narg < 4) error->all(FLERR,"Illegal dump_modify command"); // grow threshhold arrays @@ -1453,25 +1453,25 @@ int DumpCustom::modify_param(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump modify command"); + error->all(FLERR,"Invalid attribute in dump modify command"); argindex[nfield+nthresh] = atoi(ptr+1); *ptr = '\0'; } else argindex[nfield+nthresh] = 0; n = modify->find_compute(suffix); - if (n < 0) error->all("Could not find dump modify compute ID"); + if (n < 0) error->all(FLERR,"Could not find dump modify compute ID"); if (modify->compute[n]->peratom_flag == 0) - error->all("Dump modify compute ID does not compute per-atom info"); + error->all(FLERR,"Dump modify compute ID does not compute per-atom info"); if (argindex[nfield+nthresh] == 0 && modify->compute[n]->size_peratom_cols > 0) - error->all("Dump modify compute ID does not compute per-atom vector"); + error->all(FLERR,"Dump modify compute ID does not compute per-atom vector"); if (argindex[nfield+nthresh] > 0 && modify->compute[n]->size_peratom_cols == 0) - error->all("Dump modify compute ID does not compute per-atom array"); + error->all(FLERR,"Dump modify compute ID does not compute per-atom array"); if (argindex[nfield+nthresh] > 0 && argindex[nfield+nthresh] > modify->compute[n]->size_peratom_cols) - error->all("Dump modify compute ID vector is not large enough"); + error->all(FLERR,"Dump modify compute ID vector is not large enough"); field2index[nfield+nthresh] = add_compute(suffix); delete [] suffix; @@ -1491,25 +1491,25 @@ int DumpCustom::modify_param(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump modify command"); + error->all(FLERR,"Invalid attribute in dump modify command"); argindex[nfield+nthresh] = atoi(ptr+1); *ptr = '\0'; } else argindex[nfield+nthresh] = 0; n = modify->find_fix(suffix); - if (n < 0) error->all("Could not find dump modify fix ID"); + if (n < 0) error->all(FLERR,"Could not find dump modify fix ID"); if (modify->fix[n]->peratom_flag == 0) - error->all("Dump modify fix ID does not compute per-atom info"); + error->all(FLERR,"Dump modify fix ID does not compute per-atom info"); if (argindex[nfield+nthresh] == 0 && modify->fix[n]->size_peratom_cols > 0) - error->all("Dump modify fix ID does not compute per-atom vector"); + error->all(FLERR,"Dump modify fix ID does not compute per-atom vector"); if (argindex[nfield+nthresh] > 0 && modify->fix[n]->size_peratom_cols == 0) - error->all("Dump modify fix ID does not compute per-atom array"); + error->all(FLERR,"Dump modify fix ID does not compute per-atom array"); if (argindex[nfield+nthresh] > 0 && argindex[nfield+nthresh] > modify->fix[n]->size_peratom_cols) - error->all("Dump modify fix ID vector is not large enough"); + error->all(FLERR,"Dump modify fix ID vector is not large enough"); field2index[nfield+nthresh] = add_fix(suffix); delete [] suffix; @@ -1528,14 +1528,14 @@ int DumpCustom::modify_param(int narg, char **arg) argindex[nfield+nthresh] = 0; n = input->variable->find(suffix); - if (n < 0) error->all("Could not find dump modify variable name"); + if (n < 0) error->all(FLERR,"Could not find dump modify variable name"); if (input->variable->atomstyle(n) == 0) - error->all("Dump modify variable is not atom-style variable"); + error->all(FLERR,"Dump modify variable is not atom-style variable"); field2index[nfield+nthresh] = add_variable(suffix); delete [] suffix; - } else error->all("Invalid dump_modify threshhold operator"); + } else error->all(FLERR,"Invalid dump_modify threshhold operator"); // set operation type of threshhold @@ -1545,7 +1545,7 @@ int DumpCustom::modify_param(int narg, char **arg) else if (strcmp(arg[2],">=") == 0) thresh_op[nthresh] = GE; else if (strcmp(arg[2],"==") == 0) thresh_op[nthresh] = EQ; else if (strcmp(arg[2],"!=") == 0) thresh_op[nthresh] = NEQ; - else error->all("Invalid dump_modify threshhold operator"); + else error->all(FLERR,"Invalid dump_modify threshhold operator"); // set threshhold value diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp index d00c1cc5bb..a9d048f8df 100644 --- a/src/dump_dcd.cpp +++ b/src/dump_dcd.cpp @@ -55,9 +55,9 @@ static inline void fwrite_int32(FILE* fd, uint32_t i) DumpDCD::DumpDCD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg != 5) error->all("Illegal dump dcd command"); + if (narg != 5) error->all(FLERR,"Illegal dump dcd command"); if (binary || compressed || multifile || multiproc) - error->all("Invalid dump dcd filename"); + error->all(FLERR,"Invalid dump dcd filename"); size_one = 3; sort_flag = 1; @@ -69,7 +69,7 @@ DumpDCD::DumpDCD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) // allocate global array for atom coords bigint n = group->count(igroup); - if (n > MAXSMALLINT/sizeof(float)) error->all("Too many atoms for dump dcd"); + if (n > MAXSMALLINT/sizeof(float)) error->all(FLERR,"Too many atoms for dump dcd"); natoms = static_cast (n); memory->create(coords,3*natoms,"dump:coords"); @@ -95,7 +95,7 @@ DumpDCD::~DumpDCD() void DumpDCD::init_style() { if (sort_flag == 0 || sortcol != 0) - error->all("Dump dcd requires sorting by atom ID"); + error->all(FLERR,"Dump dcd requires sorting by atom ID"); // check that dump frequency has not changed and is not a variable @@ -103,11 +103,11 @@ void DumpDCD::init_style() for (idump = 0; idump < output->ndump; idump++) if (strcmp(id,output->dump[idump]->id) == 0) break; if (output->every_dump[idump] == 0) - error->all("Cannot use variable every setting for dump dcd"); + error->all(FLERR,"Cannot use variable every setting for dump dcd"); if (nevery_save == 0) nevery_save = output->every_dump[idump]; else if (nevery_save != output->every_dump[idump]) - error->all("Cannot change dump_modify every for dump dcd"); + error->all(FLERR,"Cannot change dump_modify every for dump dcd"); } /* ---------------------------------------------------------------------- */ @@ -116,7 +116,7 @@ void DumpDCD::openfile() { if (me == 0) { fp = fopen(filename,"wb"); - if (fp == NULL) error->one("Cannot open dump file"); + if (fp == NULL) error->one(FLERR,"Cannot open dump file"); } } @@ -124,9 +124,9 @@ void DumpDCD::openfile() void DumpDCD::write_header(bigint n) { - if (n != natoms) error->all("Dump dcd of non-matching # of atoms"); + if (n != natoms) error->all(FLERR,"Dump dcd of non-matching # of atoms"); if (update->ntimestep > MAXSMALLINT) - error->all("Too big a timestep for dump dcd"); + error->all(FLERR,"Too big a timestep for dump dcd"); // first time, write header for entire file @@ -266,10 +266,10 @@ void DumpDCD::write_data(int n, double *mybuf) int DumpDCD::modify_param(int narg, char **arg) { if (strcmp(arg[0],"unwrap") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[1],"yes") == 0) unwrap_flag = 1; else if (strcmp(arg[1],"no") == 0) unwrap_flag = 0; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); return 2; } return 0; diff --git a/src/dump_image.cpp b/src/dump_image.cpp index 717fb0a7f4..f01326c815 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -50,15 +50,12 @@ enum{CONTINUOUS,DISCRETE,SEQUENTIAL}; enum{ABSOLUTE,FRACTIONAL}; enum{NO,YES}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : DumpCustom(lmp, narg, arg) { - if (binary || multiproc) error->all("Invalid dump image filename"); + if (binary || multiproc) error->all(FLERR,"Invalid dump image filename"); PI = 4.0*atan(1.0); @@ -72,12 +69,12 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : else filetype = PPM; #ifndef LAMMPS_JPEG - if (filetype == JPG) error->all("Cannot dump JPG file"); + if (filetype == JPG) error->all(FLERR,"Cannot dump JPG file"); #endif // atom color,diameter settings - if (nfield != 2) error->all("Illegal dump image command"); + if (nfield != 2) error->all(FLERR,"Illegal dump image command"); acolor = ATTRIBUTE; if (strcmp(arg[5],"type") == 0) acolor = TYPE; @@ -125,47 +122,47 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : int iarg = ioptional; while (iarg < narg) { if (strcmp(arg[iarg],"adiam") == 0) { - if (iarg+2 > narg) error->all("Illegal dump image command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump image command"); adiam = NUMERIC; adiamvalue = atof(arg[iarg+1]); - if (adiamvalue <= 0.0) error->all("Illegal dump image command"); + if (adiamvalue <= 0.0) error->all(FLERR,"Illegal dump image command"); iarg += 2; } else if (strcmp(arg[iarg],"atom") == 0) { - if (iarg+2 > narg) error->all("Illegal dump image command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump image command"); if (strcmp(arg[iarg+1],"yes") == 0) atomflag = YES; else if (strcmp(arg[iarg+1],"no") == 0) atomflag = NO; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); iarg += 2; } else if (strcmp(arg[iarg],"bond") == 0) { - if (iarg+3 > narg) error->all("Illegal dump image command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command"); if (atom->nbondtypes == 0) - error->all("Dump image bond not allowed with no bond types"); + error->all(FLERR,"Dump image bond not allowed with no bond types"); bondflag = YES; if (strcmp(arg[iarg+1],"none") == 0) bondflag = NO; else if (strcmp(arg[iarg+1],"atom") == 0) bcolor = ATOM; else if (strcmp(arg[iarg+1],"type") == 0) bcolor = TYPE; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); if (!islower(arg[iarg+2][0])) { bdiam = NUMERIC; bdiamvalue = atof(arg[iarg+2]); - if (bdiamvalue <= 0.0) error->all("Illegal dump image command"); + if (bdiamvalue <= 0.0) error->all(FLERR,"Illegal dump image command"); } else if (strcmp(arg[iarg+2],"atom") == 0) bdiam = ATOM; else if (strcmp(arg[iarg+2],"type") == 0) bdiam = TYPE; else if (strcmp(arg[iarg+2],"none") == 0) bondflag = NO; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); iarg += 3; } else if (strcmp(arg[iarg],"size") == 0) { - if (iarg+3 > narg) error->all("Illegal dump image command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command"); width = atoi(arg[iarg+1]); height = atoi(arg[iarg+2]); - if (width <= 0 || height <= 0) error->all("Illegal dump image command"); + if (width <= 0 || height <= 0) error->all(FLERR,"Illegal dump image command"); iarg += 3; } else if (strcmp(arg[iarg],"view") == 0) { - if (iarg+3 > narg) error->all("Illegal dump image command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; thetastr = new char[n]; @@ -173,7 +170,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : } else { theta = atof(arg[iarg+1]); if (theta < 0.0 || theta > 180.0) - error->all("Invalid dump image theta value"); + error->all(FLERR,"Invalid dump image theta value"); theta *= PI/180.0; } if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { @@ -187,10 +184,10 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : iarg += 3; } else if (strcmp(arg[iarg],"center") == 0) { - if (iarg+5 > narg) error->all("Illegal dump image command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal dump image command"); if (strcmp(arg[iarg+1],"s") == 0) cflag = STATIC; else if (strcmp(arg[iarg+1],"d") == 0) cflag = DYNAMIC; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; cxstr = new char[n]; @@ -212,7 +209,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : iarg += 5; } else if (strcmp(arg[iarg],"up") == 0) { - if (iarg+4 > narg) error->all("Illegal dump image command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal dump image command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; upxstr = new char[n]; @@ -231,70 +228,70 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : iarg += 4; } else if (strcmp(arg[iarg],"zoom") == 0) { - if (iarg+2 > narg) error->all("Illegal dump image command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump image command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; zoomstr = new char[n]; strcpy(zoomstr,&arg[iarg+1][2]); } else { zoom = atof(arg[iarg+1]); - if (zoom <= 0.0) error->all("Illegal dump image command"); + if (zoom <= 0.0) error->all(FLERR,"Illegal dump image command"); } iarg += 2; } else if (strcmp(arg[iarg],"persp") == 0) { - error->all("Dump image persp option is not yet supported"); - if (iarg+2 > narg) error->all("Illegal dump image command"); + error->all(FLERR,"Dump image persp option is not yet supported"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump image command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; perspstr = new char[n]; strcpy(perspstr,&arg[iarg+1][2]); } else { persp = atof(arg[iarg+1]); - if (persp < 0.0) error->all("Illegal dump image command"); + if (persp < 0.0) error->all(FLERR,"Illegal dump image command"); } iarg += 2; } else if (strcmp(arg[iarg],"box") == 0) { - if (iarg+3 > narg) error->all("Illegal dump image command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command"); if (strcmp(arg[iarg+1],"yes") == 0) boxflag = YES; else if (strcmp(arg[iarg+1],"no") == 0) boxflag = NO; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); boxdiam = atof(arg[iarg+2]); - if (boxdiam < 0.0) error->all("Illegal dump image command"); + if (boxdiam < 0.0) error->all(FLERR,"Illegal dump image command"); iarg += 3; } else if (strcmp(arg[iarg],"axes") == 0) { - if (iarg+3 > narg) error->all("Illegal dump image command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command"); if (strcmp(arg[iarg+1],"yes") == 0) axesflag = YES; else if (strcmp(arg[iarg+1],"no") == 0) axesflag = NO; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); axeslen = atof(arg[iarg+2]); axesdiam = atof(arg[iarg+3]); if (axeslen < 0.0 || axesdiam < 0.0) - error->all("Illegal dump image command"); + error->all(FLERR,"Illegal dump image command"); iarg += 4; } else if (strcmp(arg[iarg],"shiny") == 0) { - if (iarg+2 > narg) error->all("Illegal dump image command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal dump image command"); shiny = atof(arg[iarg+1]); if (shiny < 0.0 || shiny > 1.0) - error->all("Illegal dump image command"); + error->all(FLERR,"Illegal dump image command"); iarg += 2; } else if (strcmp(arg[iarg],"ssao") == 0) { - if (iarg+4 > narg) error->all("Illegal dump image command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal dump image command"); if (strcmp(arg[iarg+1],"yes") == 0) ssao = YES; else if (strcmp(arg[iarg+1],"no") == 0) ssao = NO; - else error->all("Illegal dump image command"); + else error->all(FLERR,"Illegal dump image command"); seed = atoi(arg[iarg+2]); - if (seed <= 0) error->all("Illegal dump image command"); + if (seed <= 0) error->all(FLERR,"Illegal dump image command"); ssaoint = atof(arg[iarg+3]); if (ssaoint < 0.0 || ssaoint > 1.0) - error->all("Illegal dump image command"); + error->all(FLERR,"Illegal dump image command"); iarg += 4; - } else error->all("Illegal dump image command"); + } else error->all(FLERR,"Illegal dump image command"); } // params based on args @@ -449,8 +446,8 @@ DumpImage::~DumpImage() void DumpImage::init_style() { - if (multifile == 0) error->all("Dump image requires one snapshot per file"); - if (sort_flag) error->all("Dump image cannot perform sorting"); + if (multifile == 0) error->all(FLERR,"Dump image requires one snapshot per file"); + if (sort_flag) error->all(FLERR,"Dump image cannot perform sorting"); DumpCustom::init_style(); @@ -459,72 +456,72 @@ void DumpImage::init_style() if (thetastr) { thetavar = input->variable->find(thetastr); if (thetavar < 0) - error->all("Variable name for dump image theta does not exist"); + error->all(FLERR,"Variable name for dump image theta does not exist"); if (!input->variable->equalstyle(thetavar)) - error->all("Variable for dump image theta is invalid style"); + error->all(FLERR,"Variable for dump image theta is invalid style"); } if (phistr) { phivar = input->variable->find(phistr); if (phivar < 0) - error->all("Variable name for dump image phi does not exist"); + error->all(FLERR,"Variable name for dump image phi does not exist"); if (!input->variable->equalstyle(phivar)) - error->all("Variable for dump image phi is invalid style"); + error->all(FLERR,"Variable for dump image phi is invalid style"); } if (cxstr) { cxvar = input->variable->find(cxstr); if (cxvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(cxvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (cystr) { cyvar = input->variable->find(cystr); if (cyvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(cyvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (czstr) { czvar = input->variable->find(czstr); if (czvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(czvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (upxstr) { upxvar = input->variable->find(upxstr); if (upxvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(upxvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (upystr) { upyvar = input->variable->find(upystr); if (upyvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(upyvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (upzstr) { upzvar = input->variable->find(upzstr); if (upzvar < 0) - error->all("Variable name for dump image center does not exist"); + error->all(FLERR,"Variable name for dump image center does not exist"); if (!input->variable->equalstyle(upzvar)) - error->all("Variable for dump image center is invalid style"); + error->all(FLERR,"Variable for dump image center is invalid style"); } if (zoomstr) { zoomvar = input->variable->find(zoomstr); if (zoomvar < 0) - error->all("Variable name for dump image zoom does not exist"); + error->all(FLERR,"Variable name for dump image zoom does not exist"); if (!input->variable->equalstyle(zoomvar)) - error->all("Variable for dump image zoom is invalid style"); + error->all(FLERR,"Variable for dump image zoom is invalid style"); } if (perspstr) { perspvar = input->variable->find(perspstr); if (perspvar < 0) - error->all("Variable name for dump image persp does not exist"); + error->all(FLERR,"Variable name for dump image persp does not exist"); if (!input->variable->equalstyle(perspvar)) - error->all("Variable for dump image persp is invalid style"); + error->all(FLERR,"Variable for dump image persp is invalid style"); } // set up type -> element mapping @@ -533,7 +530,7 @@ void DumpImage::init_style() for (int i = 1; i <= ntypes; i++) { colorelement[i] = element2color(typenames[i]); if (colorelement[i] == NULL) - error->all("Invalid dump image element name"); + error->all(FLERR,"Invalid dump image element name"); } } @@ -541,7 +538,7 @@ void DumpImage::init_style() for (int i = 1; i <= ntypes; i++) { diamelement[i] = element2diam(typenames[i]); if (diamelement[i] == 0.0) - error->all("Invalid dump image element name"); + error->all(FLERR,"Invalid dump image element name"); } } } @@ -678,7 +675,7 @@ void DumpImage::view_params() if (thetastr) { theta = input->variable->compute_equal(thetavar); if (theta < 0.0 || theta > 180.0) - error->all("Invalid dump image theta value"); + error->all(FLERR,"Invalid dump image theta value"); theta *= PI/180.0; } if (phistr) { @@ -702,9 +699,9 @@ void DumpImage::view_params() box_bounds(); if (zoomstr) zoom = input->variable->compute_equal(zoomvar); - if (zoom <= 0.0) error->all("Invalid dump image zoom value"); + if (zoom <= 0.0) error->all(FLERR,"Invalid dump image zoom value"); if (perspstr) persp = input->variable->compute_equal(perspvar); - if (persp < 0.0) error->all("Invalid dump image persp value"); + if (persp < 0.0) error->all(FLERR,"Invalid dump image persp value"); double delx = 2.0*(boxxhi-boxxlo); double dely = 2.0*(boxyhi-boxylo); @@ -735,7 +732,7 @@ void DumpImage::view_params() MathExtra::norm3(camRight); MathExtra::cross3(camDir,camRight,camUp); if (camUp[0] == 0.0 && camUp[1] == 0.0 && camUp[2] == 0.0) - error->all("Invalid dump image up vector"); + error->all(FLERR,"Invalid dump image up vector"); MathExtra::norm3(camUp); // light directions in terms of -camDir = z @@ -832,7 +829,7 @@ void DumpImage::color_minmax() else locurrent = mlovalue; if (mhi == MAXVALUE) hicurrent = twoall[1]; else hicurrent = mhivalue; - if (locurrent > hicurrent) error->all("Invalid dump image color range"); + if (locurrent > hicurrent) error->all(FLERR,"Invalid dump image color range"); if (mstyle == CONTINUOUS) { if (mrange == ABSOLUTE) mentry[0].svalue = locurrent; @@ -1574,7 +1571,7 @@ int DumpImage::modify_param(int narg, char **arg) if (n) return n; if (strcmp(arg[0],"acolor") == 0) { - if (narg < 3) error->all("Illegal dump_modify command"); + if (narg < 3) error->all(FLERR,"Illegal dump_modify command"); int nlo,nhi; force->bounds(arg[1],atom->ntypes,nlo,nhi); @@ -1599,47 +1596,47 @@ int DumpImage::modify_param(int narg, char **arg) for (int i = nlo; i <= nhi; i++) { colortype[i] = color2rgb(ptrs[m%ncount]); if (colortype[i] == NULL) - error->all("Invalid color in dump_modify command"); + error->all(FLERR,"Invalid color in dump_modify command"); m++; } delete [] ptrs; return 3; } else if (strcmp(arg[0],"adiam") == 0) { - if (narg < 3) error->all("Illegal dump_modify command"); + if (narg < 3) error->all(FLERR,"Illegal dump_modify command"); int nlo,nhi; force->bounds(arg[1],atom->ntypes,nlo,nhi); double diam = atof(arg[2]); - if (diam <= 0.0) error->all("Illegal dump_modify command"); + if (diam <= 0.0) error->all(FLERR,"Illegal dump_modify command"); for (int i = nlo; i <= nhi; i++) diamtype[i] = diam; return 3; } else if (strcmp(arg[0],"amap") == 0) { - if (narg < 6) error->all("Illegal dump_modify command"); + if (narg < 6) error->all(FLERR,"Illegal dump_modify command"); if (!islower(arg[1][0])) { mlo = NUMERIC; mlovalue = atof(arg[1]); } else if (strcmp(arg[1],"min") == 0) mlo = MINVALUE; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); if (!islower(arg[2][0])) { mhi = NUMERIC; mhivalue = atof(arg[2]); } else if (strcmp(arg[2],"max") == 0) mhi = MAXVALUE; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); if (mlo == NUMERIC && mhi == NUMERIC && mlovalue >= mhivalue) - error->all("Illega dump_modify command"); + error->all(FLERR,"Illega dump_modify command"); - if (strlen(arg[3]) != 2) error->all("Illegal dump_modify command"); + if (strlen(arg[3]) != 2) error->all(FLERR,"Illegal dump_modify command"); if (arg[3][0] == 'c') mstyle = CONTINUOUS; else if (arg[3][0] == 'd') mstyle = DISCRETE; else if (arg[3][0] == 's') mstyle = SEQUENTIAL; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); if (arg[3][1] == 'a') mrange = ABSOLUTE; else if (arg[3][1] == 'f') mrange = FRACTIONAL; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); if (mstyle == SEQUENTIAL) { mbinsize = atof(arg[4]); - if (mbinsize <= 0.0) error->all("Illegal dump_modify command"); + if (mbinsize <= 0.0) error->all(FLERR,"Illegal dump_modify command"); } mbinsizeinv = 1.0/mbinsize; @@ -1648,61 +1645,61 @@ int DumpImage::modify_param(int narg, char **arg) int n = 6; for (int i = 0; i < nentry; i++) { if (mstyle == CONTINUOUS) { - if (n+2 > narg) error->all("Illegal dump_modify command"); + if (n+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (!islower(arg[n][0])) { mentry[i].single = NUMERIC; mentry[i].svalue = atof(arg[n]); } else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE; else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); mentry[i].color = color2rgb(arg[n+1]); n += 2; } else if (mstyle == DISCRETE) { - if (n+3 > narg) error->all("Illegal dump_modify command"); + if (n+3 > narg) error->all(FLERR,"Illegal dump_modify command"); if (!islower(arg[n][0])) { mentry[i].lo = NUMERIC; mentry[i].lvalue = atof(arg[n]); } else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE; else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); if (!islower(arg[n+1][0])) { mentry[i].hi = NUMERIC; mentry[i].hvalue = atof(arg[n+1]); } else if (strcmp(arg[n+1],"min") == 0) mentry[i].single = MINVALUE; else if (strcmp(arg[n+1],"max") == 0) mentry[i].single = MAXVALUE; - else error->all("Illegal dump_modify command"); + else error->all(FLERR,"Illegal dump_modify command"); mentry[i].color = color2rgb(arg[n+2]); n += 3; } else if (mstyle == SEQUENTIAL) { - if (n+1 > narg) error->all("Illegal dump_modify command"); + if (n+1 > narg) error->all(FLERR,"Illegal dump_modify command"); mentry[i].color = color2rgb(arg[n]); n += 1; } if (mentry[i].color == NULL) - error->all("Invalid color in dump_modify command"); + error->all(FLERR,"Invalid color in dump_modify command"); } if (mstyle == CONTINUOUS) { - if (nentry < 2) error->all("Invalid color map in dump_modify command"); + if (nentry < 2) error->all(FLERR,"Invalid color map in dump_modify command"); if (mentry[0].single != MINVALUE || mentry[nentry-1].single != MAXVALUE) - error->all("Invalid color map in dump_modify command"); + error->all(FLERR,"Invalid color map in dump_modify command"); for (int i = 2; i < nentry-1; i++) if (mentry[i].svalue <= mentry[i-1].svalue) - error->all("Invalid color map in dump_modify command"); + error->all(FLERR,"Invalid color map in dump_modify command"); } else if (mstyle == DISCRETE) { - if (nentry < 1) error->all("Invalid color map in dump_modify command"); + if (nentry < 1) error->all(FLERR,"Invalid color map in dump_modify command"); if (mentry[nentry-1].lo != MINVALUE || mentry[nentry-1].hi != MAXVALUE) - error->all("Invalid color map in dump_modify command"); + error->all(FLERR,"Invalid color map in dump_modify command"); } else if (mstyle == SEQUENTIAL) { - if (nentry < 1) error->all("Invalid color map in dump_modify command"); + if (nentry < 1) error->all(FLERR,"Invalid color map in dump_modify command"); } return n; } else if (strcmp(arg[0],"bcolor") == 0) { - if (narg < 3) error->all("Illegal dump_modify command"); + if (narg < 3) error->all(FLERR,"Illegal dump_modify command"); if (atom->nbondtypes == 0) - error->all("Dump modify bcolor not allowed with no bond types"); + error->all(FLERR,"Dump modify bcolor not allowed with no bond types"); int nlo,nhi; force->bounds(arg[1],atom->nbondtypes,nlo,nhi); @@ -1727,7 +1724,7 @@ int DumpImage::modify_param(int narg, char **arg) for (int i = nlo; i <= nhi; i++) { bcolortype[i] = color2rgb(ptrs[m%ncount]); if (bcolortype[i] == NULL) - error->all("Invalid color in dump_modify command"); + error->all(FLERR,"Invalid color in dump_modify command"); m++; } @@ -1735,33 +1732,33 @@ int DumpImage::modify_param(int narg, char **arg) return 3; } else if (strcmp(arg[0],"bdiam") == 0) { - if (narg < 3) error->all("Illegal dump_modify command"); + if (narg < 3) error->all(FLERR,"Illegal dump_modify command"); if (atom->nbondtypes == 0) - error->all("Dump modify bdiam not allowed with no bond types"); + error->all(FLERR,"Dump modify bdiam not allowed with no bond types"); int nlo,nhi; force->bounds(arg[1],atom->ntypes,nlo,nhi); double diam = atof(arg[2]); - if (diam <= 0.0) error->all("Illegal dump_modify command"); + if (diam <= 0.0) error->all(FLERR,"Illegal dump_modify command"); for (int i = nlo; i <= nhi; i++) bdiamtype[i] = diam; return 3; } else if (strcmp(arg[0],"backcolor") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); double *color = color2rgb(arg[1]); - if (color == NULL) error->all("Invalid color in dump_modify command"); + if (color == NULL) error->all(FLERR,"Invalid color in dump_modify command"); background[0] = static_cast (color[0]*255.0); background[1] = static_cast (color[1]*255.0); background[2] = static_cast (color[2]*255.0); return 2; } else if (strcmp(arg[0],"boxcolor") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); boxcolor = color2rgb(arg[1]); - if (boxcolor == NULL) error->all("Invalid color in dump_modify command"); + if (boxcolor == NULL) error->all(FLERR,"Invalid color in dump_modify command"); return 2; } else if (strcmp(arg[0],"color") == 0) { - if (narg < 5) error->all("Illegal dump_modify command"); + if (narg < 5) error->all(FLERR,"Illegal dump_modify command"); username = (char **) memory->srealloc(username,(ncolors+1)*sizeof(char *),"dump:username"); memory->grow(userrgb,ncolors+1,3,"dump:userrgb"); @@ -1774,7 +1771,7 @@ int DumpImage::modify_param(int narg, char **arg) if (userrgb[ncolors][0] < 0.0 || userrgb[ncolors][0] > 1.0 || userrgb[ncolors][1] < 0.0 || userrgb[ncolors][1] > 1.0 || userrgb[ncolors][2] < 0.0 || userrgb[ncolors][2] > 1.0) - error->all("Illegal dump_modify command"); + error->all(FLERR,"Illegal dump_modify command"); ncolors++; return 5; } diff --git a/src/dump_local.cpp b/src/dump_local.cpp index aa1bad31c6..c95f77e7c0 100644 --- a/src/dump_local.cpp +++ b/src/dump_local.cpp @@ -35,7 +35,7 @@ enum{INT,DOUBLE}; DumpLocal::DumpLocal(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg == 5) error->all("No dump local arguments specified"); + if (narg == 5) error->all(FLERR,"No dump local arguments specified"); clearstep = 1; @@ -123,7 +123,7 @@ DumpLocal::~DumpLocal() void DumpLocal::init_style() { if (sort_flag && sortcol == 0) - error->all("Dump local cannot sort by atom ID"); + error->all(FLERR,"Dump local cannot sort by atom ID"); delete [] format; char *str; @@ -152,17 +152,17 @@ void DumpLocal::init_style() int icompute; for (int i = 0; i < ncompute; i++) { icompute = modify->find_compute(id_compute[i]); - if (icompute < 0) error->all("Could not find dump local compute ID"); + if (icompute < 0) error->all(FLERR,"Could not find dump local 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 local fix ID"); + if (ifix < 0) error->all(FLERR,"Could not find dump local fix ID"); fix[i] = modify->fix[ifix]; if (nevery % modify->fix[ifix]->local_freq) - error->all("Dump local and fix not computed at compatible times"); + error->all(FLERR,"Dump local and fix not computed at compatible times"); } // open single file, one time only @@ -175,7 +175,7 @@ void DumpLocal::init_style() int DumpLocal::modify_param(int narg, char **arg) { if (strcmp(arg[0],"label") == 0) { - if (narg < 2) error->all("Illegal dump_modify command"); + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); delete [] label; int n = strlen(arg[1]) + 1; label = new char[n]; @@ -223,13 +223,13 @@ int DumpLocal::count() for (int i = 0; i < ncompute; i++) { if (nmine < 0) nmine = compute[i]->size_local_rows; else if (nmine != compute[i]->size_local_rows) - error->one("Dump local count is not consistent across input fields"); + error->one(FLERR,"Dump local count is not consistent across input fields"); } for (int i = 0; i < nfix; i++) { if (nmine < 0) nmine = fix[i]->size_local_rows; else if (nmine != fix[i]->size_local_rows) - error->one("Dump local count is not consistent across input fields"); + error->one(FLERR,"Dump local count is not consistent across input fields"); } return nmine; @@ -290,22 +290,22 @@ void DumpLocal::parse_fields(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump local command"); + error->all(FLERR,"Invalid attribute in dump local command"); argindex[i] = atoi(ptr+1); *ptr = '\0'; } else argindex[i] = 0; n = modify->find_compute(suffix); - if (n < 0) error->all("Could not find dump local compute ID"); + if (n < 0) error->all(FLERR,"Could not find dump local compute ID"); if (modify->compute[n]->local_flag == 0) - error->all("Dump local compute does not compute local info"); + error->all(FLERR,"Dump local compute does not compute local info"); if (argindex[i] == 0 && modify->compute[n]->size_local_cols > 0) - error->all("Dump local compute does not calculate local vector"); + error->all(FLERR,"Dump local compute does not calculate local vector"); if (argindex[i] > 0 && modify->compute[n]->size_local_cols == 0) - error->all("Dump local compute does not calculate local array"); + error->all(FLERR,"Dump local compute does not calculate local array"); if (argindex[i] > 0 && argindex[i] > modify->compute[n]->size_local_cols) - error->all("Dump local compute vector is accessed out-of-range"); + error->all(FLERR,"Dump local compute vector is accessed out-of-range"); field2index[i] = add_compute(suffix); delete [] suffix; @@ -325,31 +325,31 @@ void DumpLocal::parse_fields(int narg, char **arg) char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Invalid attribute in dump local command"); + error->all(FLERR,"Invalid attribute in dump local command"); argindex[i] = atoi(ptr+1); *ptr = '\0'; } else argindex[i] = 0; n = modify->find_fix(suffix); - if (n < 0) error->all("Could not find dump local fix ID"); + if (n < 0) error->all(FLERR,"Could not find dump local fix ID"); if (modify->fix[n]->local_flag == 0) - error->all("Dump local fix does not compute local info"); + error->all(FLERR,"Dump local fix does not compute local info"); if (argindex[i] == 0 && modify->fix[n]->size_local_cols > 0) - error->all("Dump local fix does not compute local vector"); + error->all(FLERR,"Dump local fix does not compute local vector"); if (argindex[i] > 0 && modify->fix[n]->size_local_cols == 0) - error->all("Dump local fix does not compute local array"); + error->all(FLERR,"Dump local fix does not compute local array"); if (argindex[i] > 0 && argindex[i] > modify->fix[n]->size_local_cols) - error->all("Dump local fix vector is accessed out-of-range"); + error->all(FLERR,"Dump local fix vector is accessed out-of-range"); field2index[i] = add_fix(suffix); delete [] suffix; - } else error->all("Invalid attribute in dump local command"); + } else error->all(FLERR,"Invalid attribute in dump local command"); } if (computefixflag == 0) - error->all("Dump local attributes contain no compute or fix"); + error->all(FLERR,"Dump local attributes contain no compute or fix"); } /* ---------------------------------------------------------------------- diff --git a/src/dump_xyz.cpp b/src/dump_xyz.cpp index d9814cdf7a..817e376fbf 100644 --- a/src/dump_xyz.cpp +++ b/src/dump_xyz.cpp @@ -24,8 +24,8 @@ using namespace LAMMPS_NS; DumpXYZ::DumpXYZ(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) { - if (narg != 5) error->all("Illegal dump xyz command"); - if (binary || multiproc) error->all("Invalid dump xyz filename"); + if (narg != 5) error->all(FLERR,"Illegal dump xyz command"); + if (binary || multiproc) error->all(FLERR,"Invalid dump xyz filename"); size_one = 5; sort_flag = 1; diff --git a/src/error.cpp b/src/error.cpp index 81f40a5498..283d872baf 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -29,13 +29,15 @@ Error::Error(LAMMPS *lmp) : Pointers(lmp) {} close all output, screen, and log files in world and universe ------------------------------------------------------------------------- */ -void Error::universe_all(const char *str) +void Error::universe_all(const char *file, int line, const char *str) { MPI_Barrier(universe->uworld); if (universe->me == 0) { - if (universe->uscreen) fprintf(universe->uscreen,"ERROR: %s\n",str); - if (universe->ulogfile) fprintf(universe->ulogfile,"ERROR: %s\n",str); + if (universe->uscreen) fprintf(universe->uscreen, + "ERROR: %s (%s:%d)\n",str,file,line); + if (universe->ulogfile) fprintf(universe->ulogfile, + "ERROR: %s (%s:%d)\n",str,file,line); } if (output) delete output; @@ -53,10 +55,11 @@ void Error::universe_all(const char *str) called by one proc in universe ------------------------------------------------------------------------- */ -void Error::universe_one(const char *str) +void Error::universe_one(const char *file, int line, const char *str) { if (universe->uscreen) - fprintf(universe->uscreen,"ERROR on proc %d: %s\n",universe->me,str); + fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n", + universe->me,str,file,line); MPI_Abort(universe->uworld,1); } @@ -65,7 +68,7 @@ void Error::universe_one(const char *str) close all output, screen, and log files in world ------------------------------------------------------------------------- */ -void Error::all(const char *str) +void Error::all(const char *file, int line, const char *str) { MPI_Barrier(world); @@ -73,8 +76,8 @@ void Error::all(const char *str) MPI_Comm_rank(world,&me); if (me == 0) { - if (screen) fprintf(screen,"ERROR: %s\n",str); - if (logfile) fprintf(logfile,"ERROR: %s\n",str); + if (screen) fprintf(screen,"ERROR: %s (%s:%d)\n",str,file,line); + if (logfile) fprintf(logfile,"ERROR: %s (%s:%d)\n",str,file,line); } if (output) delete output; @@ -91,13 +94,14 @@ void Error::all(const char *str) always write to universe screen ------------------------------------------------------------------------- */ -void Error::one(const char *str) +void Error::one(const char *file, int line, const char *str) { int me; MPI_Comm_rank(world,&me); - if (screen) fprintf(screen,"ERROR on proc %d: %s\n",me,str); + if (screen) fprintf(screen,"ERROR on proc %d: %s (%s:%d)\n",me,str,file,line); if (universe->nworlds > 1) - fprintf(universe->uscreen,"ERROR on proc %d: %s\n",universe->me,str); + fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n", + universe->me,str,file,line); MPI_Abort(world,1); } @@ -106,10 +110,11 @@ void Error::one(const char *str) only write to screen if non-NULL on this proc since could be file ------------------------------------------------------------------------- */ -void Error::warning(const char *str, int logflag) +void Error::warning(const char *file, int line, const char *str, int logflag) { - if (screen) fprintf(screen,"WARNING: %s\n",str); - if (logflag && logfile) fprintf(logfile,"WARNING: %s\n",str); + if (screen) fprintf(screen,"WARNING: %s (%s:%d)\n",str,file,line); + if (logflag && logfile) fprintf(logfile,"WARNING: %s (%s:%d)\n", + str,file,line); } /* ---------------------------------------------------------------------- @@ -117,10 +122,10 @@ void Error::warning(const char *str, int logflag) write message to screen and logfile (if logflag is set) ------------------------------------------------------------------------- */ -void Error::message(char *str, int logflag) +void Error::message(const char *file, int line, char *str, int logflag) { - if (screen) fprintf(screen,"%s\n",str); - if (logflag && logfile) fprintf(logfile,"%s\n",str); + if (screen) fprintf(screen,"%s (%s:%d)\n",str,file,line); + if (logflag && logfile) fprintf(logfile,"%s (%s:%d)\n",str,file,line); } /* ---------------------------------------------------------------------- diff --git a/src/error.h b/src/error.h index 8c55a046c9..395581dee3 100644 --- a/src/error.h +++ b/src/error.h @@ -22,13 +22,13 @@ class Error : protected Pointers { public: Error(class LAMMPS *); - void universe_all(const char *); - void universe_one(const char *); + void universe_all(const char *, int, const char *); + void universe_one(const char *, int, const char *); - void all(const char *); - void one(const char *); - void warning(const char *, int = 1); - void message(char *, int = 1); + void all(const char *, int, const char *); + void one(const char *, int, const char *); + void warning(const char *, int, const char *, int = 1); + void message(const char *, int, char *, int = 1); void done(); }; diff --git a/src/finish.cpp b/src/finish.cpp index 52fc2f312c..fb43f1c7ba 100644 --- a/src/finish.cpp +++ b/src/finish.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ Finish::Finish(LAMMPS *lmp) : Pointers(lmp) {} diff --git a/src/fix.cpp b/src/fix.cpp index 2ed2dc7485..dc4263b7d1 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -34,10 +34,10 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) for (int i = 0; i < n-1; i++) if (!isalnum(id[i]) && id[i] != '_') - error->all("Fix ID must be alphanumeric or underscore characters"); + error->all(FLERR,"Fix ID must be alphanumeric or underscore characters"); igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find fix group ID"); + if (igroup == -1) error->all(FLERR,"Could not find fix group ID"); groupbit = group->bitmask[igroup]; n = strlen(arg[2]) + 1; @@ -107,19 +107,19 @@ Fix::~Fix() void Fix::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal fix_modify command"); + if (narg == 0) error->all(FLERR,"Illegal fix_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"energy") == 0) { - if (iarg+2 > narg) error->all("Illegal fix_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); if (strcmp(arg[iarg+1],"no") == 0) thermo_energy = 0; else if (strcmp(arg[iarg+1],"yes") == 0) thermo_energy = 1; - else error->all("Illegal fix_modify command"); + else error->all(FLERR,"Illegal fix_modify command"); iarg += 2; } else { int n = modify_param(narg-iarg,&arg[iarg]); - if (n == 0) error->all("Illegal fix_modify command"); + if (n == 0) error->all(FLERR,"Illegal fix_modify command"); iarg += n; } } diff --git a/src/fix_adapt.cpp b/src/fix_adapt.cpp index d5825b5616..fd1a256b8a 100644 --- a/src/fix_adapt.cpp +++ b/src/fix_adapt.cpp @@ -32,16 +32,13 @@ using namespace LAMMPS_NS; enum{PAIR,KSPACE,ATOM}; enum{DIAMETER}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix adapt command"); + if (narg < 5) error->all(FLERR,"Illegal fix adapt command"); nevery = atoi(arg[3]); - if (nevery < 0) error->all("Illegal fix adapt command"); + if (nevery < 0) error->all(FLERR,"Illegal fix adapt command"); // count # of adaptations @@ -50,21 +47,21 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) int iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"pair") == 0) { - if (iarg+6 > narg) error->all("Illegal fix adapt command"); + if (iarg+6 > narg) error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 6; } else if (strcmp(arg[iarg],"kspace") == 0) { - if (iarg+2 > narg) error->all("Illegal fix adapt command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 2; } else if (strcmp(arg[iarg],"atom") == 0) { - if (iarg+3 > narg) error->all("Illegal fix adapt command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 3; } else break; } - if (nadapt == 0) error->all("Illegal fix adapt command"); + if (nadapt == 0) error->all(FLERR,"Illegal fix adapt command"); adapt = new Adapt[nadapt]; // parse keywords @@ -75,7 +72,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"pair") == 0) { - if (iarg+6 > narg) error->all("Illegal fix adapt command"); + if (iarg+6 > narg) error->all(FLERR,"Illegal fix adapt command"); adapt[nadapt].which = PAIR; int n = strlen(arg[iarg+1]) + 1; adapt[nadapt].pstyle = new char[n]; @@ -91,31 +88,31 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) n = strlen(&arg[iarg+5][2]) + 1; adapt[nadapt].var = new char[n]; strcpy(adapt[nadapt].var,&arg[iarg+5][2]); - } else error->all("Illegal fix adapt command"); + } else error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 6; } else if (strcmp(arg[iarg],"kspace") == 0) { - if (iarg+2 > narg) error->all("Illegal fix adapt command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt command"); adapt[nadapt].which = KSPACE; if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; adapt[nadapt].var = new char[n]; strcpy(adapt[nadapt].var,&arg[iarg+1][2]); - } else error->all("Illegal fix adapt command"); + } else error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 2; } else if (strcmp(arg[iarg],"atom") == 0) { - if (iarg+3 > narg) error->all("Illegal fix adapt command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix adapt command"); adapt[nadapt].which = ATOM; if (strcmp(arg[iarg+1],"diameter") == 0) { adapt[nadapt].aparam = DIAMETER; diamflag = 1; - } else error->all("Illegal fix adapt command"); + } else error->all(FLERR,"Illegal fix adapt command"); if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; adapt[nadapt].var = new char[n]; strcpy(adapt[nadapt].var,&arg[iarg+2][2]); - } else error->all("Illegal fix adapt command"); + } else error->all(FLERR,"Illegal fix adapt command"); nadapt++; iarg += 3; } else break; @@ -128,18 +125,18 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) while (iarg < narg) { if (strcmp(arg[iarg],"reset") == 0) { - if (iarg+2 > narg) error->all("Illegal fix adapt command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt command"); if (strcmp(arg[iarg+1],"no") == 0) resetflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) resetflag = 1; - else error->all("Illegal fix adapt command"); + else error->all(FLERR,"Illegal fix adapt command"); iarg += 2; } else if (strcmp(arg[iarg],"scale") == 0) { - if (iarg+2 > narg) error->all("Illegal fix adapt command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt command"); if (strcmp(arg[iarg+1],"no") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) scaleflag = 1; - else error->all("Illegal fix adapt command"); + else error->all(FLERR,"Illegal fix adapt command"); iarg += 2; - } else error->all("Illegal fix adapt command"); + } else error->all(FLERR,"Illegal fix adapt command"); } // allocate pair style arrays @@ -190,17 +187,17 @@ void FixAdapt::init() ad->ivar = input->variable->find(ad->var); if (ad->ivar < 0) - error->all("Variable name for fix adapt does not exist"); + error->all(FLERR,"Variable name for fix adapt does not exist"); if (!input->variable->equalstyle(ad->ivar)) - error->all("Variable for fix adapt is invalid style"); + error->all(FLERR,"Variable for fix adapt is invalid style"); if (ad->which == PAIR) { anypair = 1; Pair *pair = force->pair_match(ad->pstyle,1); - if (pair == NULL) error->all("Fix adapt pair style does not exist"); + if (pair == NULL) error->all(FLERR,"Fix adapt pair style does not exist"); void *ptr = pair->extract(ad->pparam,ad->pdim); - if (ptr == NULL) error->all("Fix adapt pair style param not supported"); + if (ptr == NULL) error->all(FLERR,"Fix adapt pair style param not supported"); ad->pdim = 2; if (ad->pdim == 0) ad->scalar = (double *) ptr; @@ -214,19 +211,19 @@ void FixAdapt::init() for (i = ad->ilo; i <= ad->ihi; i++) for (j = MAX(ad->jlo,i); j <= ad->jhi; j++) if (!pair->check_ijtype(i,j,ad->pstyle)) - error->all("Fix adapt type pair range is not valid for " + error->all(FLERR,"Fix adapt type pair range is not valid for " "pair hybrid sub-style"); } } else if (ad->which == KSPACE) { if (force->kspace == NULL) - error->all("Fix adapt kspace style does not exist"); + error->all(FLERR,"Fix adapt kspace style does not exist"); kspace_scale = (double *) force->kspace->extract("scale"); } else if (ad->which == ATOM) { if (ad->aparam == DIAMETER) { if (!atom->radius_flag) - error->all("Fix adapt requires atom attribute diameter"); + error->all(FLERR,"Fix adapt requires atom attribute diameter"); } } } diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp index fa5c3be606..16a3c1feab 100644 --- a/src/fix_addforce.cpp +++ b/src/fix_addforce.cpp @@ -34,7 +34,7 @@ enum{NONE,CONSTANT,EQUAL,ATOM}; FixAddForce::FixAddForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix addforce command"); + if (narg < 6) error->all(FLERR,"Illegal fix addforce command"); scalar_flag = 1; vector_flag = 1; @@ -79,23 +79,23 @@ FixAddForce::FixAddForce(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix addforce command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix addforce command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) - error->all("Region ID for fix addforce does not exist"); + error->all(FLERR,"Region ID for fix addforce does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"energy") == 0) { - if (iarg+2 > narg) error->all("Illegal fix addforce command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix addforce command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; estr = new char[n]; strcpy(estr,&arg[iarg+1][2]); - } else error->all("Illegal fix addforce command"); + } else error->all(FLERR,"Illegal fix addforce command"); iarg += 2; - } else error->all("Illegal fix addforce command"); + } else error->all(FLERR,"Illegal fix addforce command"); } force_flag = 0; @@ -137,37 +137,37 @@ void FixAddForce::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix addforce does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; - else error->all("Variable for fix addforce is invalid style"); + else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix addforce does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; - else error->all("Variable for fix addforce is invalid style"); + else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix addforce does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; - else error->all("Variable for fix addforce is invalid style"); + else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (estr) { evar = input->variable->find(estr); - if (evar < 0) error->all("Variable name for fix addforce does not exist"); + if (evar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->atomstyle(evar)) estyle = ATOM; - else error->all("Variable for fix addforce is invalid style"); + else error->all(FLERR,"Variable for fix addforce is invalid style"); } else estyle = NONE; // set index and check validity of region if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for fix addforce does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix addforce does not exist"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) @@ -177,11 +177,11 @@ void FixAddForce::init() else varflag = CONSTANT; if (varflag == CONSTANT && estyle != NONE) - error->all("Cannot use variable energy with " + error->all(FLERR,"Cannot use variable energy with " "constant force in fix addforce"); if ((varflag == EQUAL || varflag == ATOM) && update->whichflag == 2 && estyle == NONE) - error->all("Must use variable energy with fix addforce"); + error->all(FLERR,"Must use variable energy with fix addforce"); if (strstr(update->integrate_style,"respa")) nlevels_respa = ((Respa *) update->integrate)->nlevels; diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp index b604977f7e..01f21f9508 100644 --- a/src/fix_ave_atom.cpp +++ b/src/fix_ave_atom.cpp @@ -36,7 +36,7 @@ enum{X,V,F,COMPUTE,FIX,VARIABLE}; FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix ave/atom command"); + if (narg < 7) error->all(FLERR,"Illegal fix ave/atom command"); time_depend = 1; @@ -100,7 +100,7 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix ave/atom command"); + error->all(FLERR,"Illegal fix ave/atom command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -111,7 +111,7 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : nvalues++; delete [] suffix; - } else error->all("Illegal fix ave/atom command"); + } else error->all(FLERR,"Illegal fix ave/atom command"); iarg++; } @@ -120,49 +120,49 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : // for fix inputs, check that fix frequency is acceptable if (nevery <= 0 || nrepeat <= 0 || peratom_freq <= 0) - error->all("Illegal fix ave/atom command"); + error->all(FLERR,"Illegal fix ave/atom command"); if (peratom_freq % nevery || (nrepeat-1)*nevery >= peratom_freq) - error->all("Illegal fix ave/atom command"); + error->all(FLERR,"Illegal fix ave/atom command"); for (int i = 0; i < nvalues; i++) { if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/atom does not exist"); + error->all(FLERR,"Compute ID for fix ave/atom does not exist"); if (modify->compute[icompute]->peratom_flag == 0) - error->all("Fix ave/atom compute does not calculate per-atom values"); + error->all(FLERR,"Fix ave/atom compute does not calculate per-atom values"); if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Fix ave/atom compute does not " + error->all(FLERR,"Fix ave/atom compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Fix ave/atom compute does not " + error->all(FLERR,"Fix ave/atom compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Fix ave/atom compute array is accessed out-of-range"); + error->all(FLERR,"Fix ave/atom compute array is accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/atom does not exist"); + error->all(FLERR,"Fix ID for fix ave/atom does not exist"); if (modify->fix[ifix]->peratom_flag == 0) - error->all("Fix ave/atom fix does not calculate per-atom values"); + error->all(FLERR,"Fix ave/atom fix does not calculate per-atom values"); if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Fix ave/atom fix does not calculate a per-atom vector"); + error->all(FLERR,"Fix ave/atom fix does not calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Fix ave/atom fix does not calculate a per-atom array"); + error->all(FLERR,"Fix ave/atom fix does not calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Fix ave/atom fix array is accessed out-of-range"); + error->all(FLERR,"Fix ave/atom fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->peratom_freq) - error->all("Fix for fix ave/atom not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/atom not computed at compatible time"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/atom does not exist"); + error->all(FLERR,"Variable name for fix ave/atom does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all("Fix ave/atom variable is not atom-style variable"); + error->all(FLERR,"Fix ave/atom variable is not atom-style variable"); } } @@ -233,19 +233,19 @@ void FixAveAtom::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for fix ave/atom does not exist"); + error->all(FLERR,"Compute ID for fix ave/atom does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for fix ave/atom does not exist"); + error->all(FLERR,"Fix ID for fix ave/atom does not exist"); value2index[m] = ifix; } else if (which[m] == VARIABLE) { int ivariable = input->variable->find(ids[m]); if (ivariable < 0) - error->all("Variable name for fix ave/atom does not exist"); + error->all(FLERR,"Variable name for fix ave/atom does not exist"); value2index[m] = ivariable; } else value2index[m] = -1; diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp index 9abf3e46d2..b84fc06b4d 100644 --- a/src/fix_ave_correlate.cpp +++ b/src/fix_ave_correlate.cpp @@ -44,7 +44,7 @@ enum{AUTO,UPPER,LOWER,AUTOUPPER,AUTOLOWER,FULL}; FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): Fix (lmp, narg, arg) { - if (narg < 7) error->all ("Illegal fix ave/correlate command"); + if (narg < 7) error->all(FLERR,"Illegal fix ave/correlate command"); MPI_Comm_rank(world,&me); @@ -79,7 +79,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix ave/correlate command"); + error->all(FLERR,"Illegal fix ave/correlate command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -107,107 +107,111 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): while (iarg < narg) { if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); if (strcmp(arg[iarg+1],"auto") == 0) type = AUTO; else if (strcmp(arg[iarg+1],"upper") == 0) type = UPPER; else if (strcmp(arg[iarg+1],"lower") == 0) type = LOWER; else if (strcmp(arg[iarg+1],"auto/upper") == 0) type = AUTOUPPER; else if (strcmp(arg[iarg+1],"auto/lower") == 0) type = AUTOLOWER; else if (strcmp(arg[iarg+1],"full") == 0) type = FULL; - else error->all("Illegal fix ave/correlate command"); + else error->all(FLERR,"Illegal fix ave/correlate command"); iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; - else error->all("Illegal fix ave/correlate command"); + else error->all(FLERR,"Illegal fix ave/correlate command"); iarg += 2; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); startstep = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"prefactor") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); prefactor = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); if (me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix ave/correlate file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); delete [] title1; int n = strlen(arg[iarg+1]) + 1; title1 = new char[n]; strcpy(title1,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); delete [] title2; int n = strlen(arg[iarg+1]) + 1; title2 = new char[n]; strcpy(title2,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/correlate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); delete [] title3; int n = strlen(arg[iarg+1]) + 1; title3 = new char[n]; strcpy(title3,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix ave/correlate command"); + } else error->all(FLERR,"Illegal fix ave/correlate command"); } // setup and error check // for fix inputs, check that fix frequency is acceptable if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all("Illegal fix ave/correlate command"); + error->all(FLERR,"Illegal fix ave/correlate command"); if (nfreq % nevery) - error->all("Illegal fix ave/correlate command"); + error->all(FLERR,"Illegal fix ave/correlate command"); if (ave == ONE && nfreq < (nrepeat-1)*nevery) - error->all("Illegal fix ave/correlate command"); + error->all(FLERR,"Illegal fix ave/correlate command"); for (int i = 0; i < nvalues; i++) { if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all ("Compute ID for fix ave/correlate does not exist"); + error->all(FLERR,"Compute ID for fix ave/correlate does not exist"); if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all ("Fix ave/correlate compute does not calculate a scalar"); + error->all(FLERR, + "Fix ave/correlate compute does not calculate a scalar"); if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all ("Fix ave/correlate compute does not calculate a vector"); + error->all(FLERR, + "Fix ave/correlate compute does not calculate a vector"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all ("Fix ave/correlate compute vector " - "is accessed out-of-range"); + error->all(FLERR,"Fix ave/correlate compute vector " + "is accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all ("Fix ID for fix ave/correlate does not exist"); + error->all(FLERR,"Fix ID for fix ave/correlate does not exist"); if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all ("Fix ave/correlate fix does not calculate a scalar"); + error->all(FLERR,"Fix ave/correlate fix does not calculate a scalar"); if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all ("Fix ave/correlate fix does not calculate a vector"); + error->all(FLERR,"Fix ave/correlate fix does not calculate a vector"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all ("Fix ave/correlate fix vector is accessed out-of-range"); + error->all(FLERR, + "Fix ave/correlate fix vector is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/correlate " + error->all(FLERR,"Fix for fix ave/correlate " "not computed at compatible time"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all ("Variable name for fix ave/correlate does not exist"); + error->all(FLERR,"Variable name for fix ave/correlate does not exist"); if (input->variable->equalstyle(ivariable) == 0) - error->all ("Fix ave/correlate variable is not equal-style variable"); + error->all(FLERR, + "Fix ave/correlate variable is not equal-style variable"); } } @@ -333,19 +337,19 @@ void FixAveCorrelate::init() if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/correlate does not exist"); + error->all(FLERR,"Compute ID for fix ave/correlate does not exist"); value2index[i] = icompute; } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/correlate does not exist"); + error->all(FLERR,"Fix ID for fix ave/correlate does not exist"); value2index[i] = ifix; } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/correlate does not exist"); + error->all(FLERR,"Variable name for fix ave/correlate does not exist"); value2index[i] = ivariable; } } diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp index 6692681f19..f7909ac258 100644 --- a/src/fix_ave_histo.cpp +++ b/src/fix_ave_histo.cpp @@ -40,15 +40,12 @@ enum{IGNORE,END,EXTRA}; #define INVOKED_LOCAL 16 #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 10) error->all("Illegal fix ave/histo command"); + if (narg < 10) error->all(FLERR,"Illegal fix ave/histo command"); MPI_Comm_rank(world,&me); @@ -179,7 +176,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix ave/histo command"); + error->all(FLERR,"Illegal fix ave/histo command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -193,7 +190,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : argindex[nvalues] == 0) { int icompute = modify->find_compute(ids[nvalues]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); if (modify->compute[icompute]->array_flag) { int ncols = modify->compute[icompute]->size_array_cols; maxvalues += ncols-1; @@ -213,7 +210,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : argindex[nvalues] == 0) { int ifix = modify->find_fix(ids[nvalues]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); if (modify->fix[ifix]->array_flag) { int ncols = modify->fix[ifix]->size_array_cols; maxvalues += ncols-1; @@ -240,11 +237,11 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : // for fix inputs, check that fix frequency is acceptable if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all("Illegal fix ave/histo command"); + error->all(FLERR,"Illegal fix ave/histo command"); if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq) - error->all("Illegal fix ave/histo command"); - if (lo >= hi) error->all("Illegal fix ave/histo command"); - if (nbins <= 0) error->all("Illegal fix ave/histo command"); + error->all(FLERR,"Illegal fix ave/histo command"); + if (lo >= hi) error->all(FLERR,"Illegal fix ave/histo command"); + if (nbins <= 0) error->all(FLERR,"Illegal fix ave/histo command"); int kindflag; for (int i = 0; i < nvalues; i++) { @@ -255,161 +252,161 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : kindflag = GLOBAL; else if (compute->peratom_flag) kindflag = PERATOM; else if (compute->local_flag) kindflag = LOCAL; - else error->all("Fix ave/histo input is invalid compute"); + else error->all(FLERR,"Fix ave/histo input is invalid compute"); } else if (which[i] == FIX) { Fix *fix = modify->fix[modify->find_fix(ids[0])]; if (fix->scalar_flag || fix->vector_flag || fix->array_flag) kindflag = GLOBAL; else if (fix->peratom_flag) kindflag = PERATOM; else if (fix->local_flag) kindflag = LOCAL; - else error->all("Fix ave/histo input is invalid fix"); + else error->all(FLERR,"Fix ave/histo input is invalid fix"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (input->variable->equalstyle(ivariable)) kindflag = GLOBAL; else if (input->variable->atomstyle(ivariable)) kindflag = PERATOM; - else error->all("Fix ave/histo input is invalid variable"); + else error->all(FLERR,"Fix ave/histo input is invalid variable"); } if (i == 0) kind = kindflag; else if (kindflag != kind) - error->all("Fix ave/histo inputs are not all global, peratom, or local"); + error->all(FLERR,"Fix ave/histo inputs are not all global, peratom, or local"); } if (kind == PERATOM && mode == SCALAR) - error->all("Fix ave/histo cannot input per-atom values in scalar mode"); + error->all(FLERR,"Fix ave/histo cannot input per-atom values in scalar mode"); if (kind == LOCAL && mode == SCALAR) - error->all("Fix ave/histo cannot input local values in scalar mode"); + error->all(FLERR,"Fix ave/histo cannot input local values in scalar mode"); for (int i = 0; i < nvalues; i++) { if (which[i] == COMPUTE && kind == GLOBAL && mode == SCALAR) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all("Fix ave/histo compute does not calculate a global scalar"); + error->all(FLERR,"Fix ave/histo compute does not calculate a global scalar"); if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all("Fix ave/histo compute does not calculate a global vector"); + error->all(FLERR,"Fix ave/histo compute does not calculate a global vector"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all("Fix ave/histo compute vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo compute vector is accessed out-of-range"); } else if (which[i] == COMPUTE && kind == GLOBAL && mode == VECTOR) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); if (argindex[i] == 0 && modify->compute[icompute]->vector_flag == 0) - error->all("Fix ave/histo compute does not calculate a global vector"); + error->all(FLERR,"Fix ave/histo compute does not calculate a global vector"); if (argindex[i] && modify->compute[icompute]->array_flag == 0) - error->all("Fix ave/histo compute does not calculate a global array"); + error->all(FLERR,"Fix ave/histo compute does not calculate a global array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_array_cols) - error->all("Fix ave/histo compute array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo compute array is accessed out-of-range"); } else if (which[i] == COMPUTE && kind == PERATOM) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); if (modify->compute[icompute]->peratom_flag == 0) - error->all("Fix ave/histo compute does not calculate per-atom values"); + error->all(FLERR,"Fix ave/histo compute does not calculate per-atom values"); if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Fix ave/histo compute does not " + error->all(FLERR,"Fix ave/histo compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Fix ave/histo compute does not " + error->all(FLERR,"Fix ave/histo compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Fix ave/histo compute array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo compute array is accessed out-of-range"); } else if (which[i] == COMPUTE && kind == LOCAL) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); if (modify->compute[icompute]->local_flag == 0) - error->all("Fix ave/histo compute does not calculate local values"); + error->all(FLERR,"Fix ave/histo compute does not calculate local values"); if (argindex[i] == 0 && modify->compute[icompute]->size_local_cols != 0) - error->all("Fix ave/histo compute does not " + error->all(FLERR,"Fix ave/histo compute does not " "calculate a local vector"); if (argindex[i] && modify->compute[icompute]->size_local_cols == 0) - error->all("Fix ave/histo compute does not " + error->all(FLERR,"Fix ave/histo compute does not " "calculate a local array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_local_cols) - error->all("Fix ave/histo compute array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo compute array is accessed out-of-range"); } else if (which[i] == FIX && kind == GLOBAL && mode == SCALAR) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all("Fix ave/histo fix does not calculate a global scalar"); + error->all(FLERR,"Fix ave/histo fix does not calculate a global scalar"); if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all("Fix ave/histo fix does not calculate a global vector"); + error->all(FLERR,"Fix ave/histo fix does not calculate a global vector"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all("Fix ave/histo fix vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo fix vector is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/histo not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/histo not computed at compatible time"); } else if (which[i] == FIX && kind == GLOBAL && mode == VECTOR) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); if (argindex[i] == 0 && modify->fix[ifix]->vector_flag == 0) - error->all("Fix ave/histo fix does not calculate a global vector"); + error->all(FLERR,"Fix ave/histo fix does not calculate a global vector"); if (argindex[i] && modify->fix[ifix]->array_flag == 0) - error->all("Fix ave/histo fix does not calculate a global array"); + error->all(FLERR,"Fix ave/histo fix does not calculate a global array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_array_cols) - error->all("Fix ave/histo fix array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/histo not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/histo not computed at compatible time"); } else if (which[i] == FIX && kind == PERATOM) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); if (modify->fix[ifix]->peratom_flag == 0) - error->all("Fix ave/histo fix does not calculate per-atom values"); + error->all(FLERR,"Fix ave/histo fix does not calculate per-atom values"); if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Fix ave/histo fix does not " + error->all(FLERR,"Fix ave/histo fix does not " "calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Fix ave/histo fix does not " + error->all(FLERR,"Fix ave/histo fix does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Fix ave/histo fix array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/histo not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/histo not computed at compatible time"); } else if (which[i] == FIX && kind == LOCAL) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); if (modify->fix[ifix]->local_flag == 0) - error->all("Fix ave/histo fix does not calculate local values"); + error->all(FLERR,"Fix ave/histo fix does not calculate local values"); if (argindex[i] == 0 && modify->fix[ifix]->size_local_cols != 0) - error->all("Fix ave/histo fix does not " + error->all(FLERR,"Fix ave/histo fix does not " "calculate a local vector"); if (argindex[i] && modify->fix[ifix]->size_local_cols == 0) - error->all("Fix ave/histo fix does not " + error->all(FLERR,"Fix ave/histo fix does not " "calculate a local array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_local_cols) - error->all("Fix ave/histo fix array is accessed out-of-range"); + error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/histo not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/histo not computed at compatible time"); } else if (which[i] == VARIABLE && kind == GLOBAL) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/histo does not exist"); + error->all(FLERR,"Variable name for fix ave/histo does not exist"); } else if (which[i] == VARIABLE && kind == PERATOM) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/histo does not exist"); + error->all(FLERR,"Variable name for fix ave/histo does not exist"); } } @@ -524,19 +521,19 @@ void FixAveHisto::init() if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/histo does not exist"); + error->all(FLERR,"Compute ID for fix ave/histo does not exist"); value2index[i] = icompute; } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/histo does not exist"); + error->all(FLERR,"Fix ID for fix ave/histo does not exist"); value2index[i] = ifix; } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/histo does not exist"); + error->all(FLERR,"Variable name for fix ave/histo does not exist"); value2index[i] = ivariable; } } @@ -901,68 +898,68 @@ void FixAveHisto::options(int narg, char **arg) int iarg = 9 + nvalues; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); if (me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix ave/histo file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; - else error->all("Illegal fix ave/histo command"); + else error->all(FLERR,"Illegal fix ave/histo command"); if (ave == WINDOW) { - if (iarg+3 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/histo command"); nwindow = atoi(arg[iarg+2]); - if (nwindow <= 0) error->all("Illegal fix ave/histo command"); + if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/histo command"); } iarg += 2; if (ave == WINDOW) iarg++; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); startstep = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"mode") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR; else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR; - else error->all("Illegal fix ave/histo command"); + else error->all(FLERR,"Illegal fix ave/histo command"); iarg += 2; } else if (strcmp(arg[iarg],"beyond") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/histo command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); if (strcmp(arg[iarg+1],"ignore") == 0) beyond = IGNORE; else if (strcmp(arg[iarg+1],"end") == 0) beyond = END; else if (strcmp(arg[iarg+1],"extra") == 0) beyond = EXTRA; - else error->all("Illegal fix ave/histo command"); + else error->all(FLERR,"Illegal fix ave/histo command"); iarg += 2; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title1; int n = strlen(arg[iarg+1]) + 1; title1 = new char[n]; strcpy(title1,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title2; int n = strlen(arg[iarg+1]) + 1; title2 = new char[n]; strcpy(title2,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title3; int n = strlen(arg[iarg+1]) + 1; title3 = new char[n]; strcpy(title3,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix ave/histo command"); + } else error->all(FLERR,"Illegal fix ave/histo command"); } } diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp index e1b47e5015..0fd4672ecf 100644 --- a/src/fix_ave_spatial.cpp +++ b/src/fix_ave_spatial.cpp @@ -43,15 +43,12 @@ enum{ONE,RUNNING,WINDOW}; #define INVOKED_PERATOM 8 #define BIG 1000000000 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix ave/spatial command"); + if (narg < 6) error->all(FLERR,"Illegal fix ave/spatial command"); MPI_Comm_rank(world,&me); @@ -73,7 +70,7 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : else break; if (dim[ndim] == 2 && domain->dimension == 2) - error->all("Cannot use fix ave/spatial z for 2 dimensional model"); + error->all(FLERR,"Cannot use fix ave/spatial z for 2 dimensional model"); if (strcmp(arg[iarg+1],"lower") == 0) originflag[ndim] = LOWER; if (strcmp(arg[iarg+1],"center") == 0) originflag[ndim] = CENTER; @@ -86,11 +83,11 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : iarg += 3; } - if (!ndim) error->all("Illegal fix ave/spatial command"); + if (!ndim) error->all(FLERR,"Illegal fix ave/spatial command"); if (ndim == 2 && dim[0] == dim[1]) - error->all("Same dimension twice in fix ave/spatial"); + error->all(FLERR,"Same dimension twice in fix ave/spatial"); if (ndim == 3 && (dim[0] == dim[1] || dim[1] == dim[2] || dim[0] == dim[2])) - error->all("Same dimension twice in fix ave/spatial"); + error->all(FLERR,"Same dimension twice in fix ave/spatial"); // parse values until one isn't recognized @@ -144,7 +141,7 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix ave/spatial command"); + error->all(FLERR,"Illegal fix ave/spatial command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -175,125 +172,125 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"norm") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); if (strcmp(arg[iarg+1],"all") == 0) normflag = ALL; else if (strcmp(arg[iarg+1],"sample") == 0) normflag = SAMPLE; - else error->all("Illegal fix ave/spatial command"); + else error->all(FLERR,"Illegal fix ave/spatial command"); iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = BOX; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = LATTICE; else if (strcmp(arg[iarg+1],"reduced") == 0) scaleflag = REDUCED; - else error->all("Illegal fix ave/spatial command"); + else error->all(FLERR,"Illegal fix ave/spatial command"); iarg += 2; } else if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) - error->all("Region ID for fix ave/spatial does not exist"); + error->all(FLERR,"Region ID for fix ave/spatial does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); regionflag = 1; iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); if (me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix ave/spatial file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; - else error->all("Illegal fix ave/spatial command"); + else error->all(FLERR,"Illegal fix ave/spatial command"); if (ave == WINDOW) { - if (iarg+3 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); nwindow = atoi(arg[iarg+2]); - if (nwindow <= 0) error->all("Illegal fix ave/spatial command"); + if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/spatial command"); } iarg += 2; if (ave == WINDOW) iarg++; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title1; int n = strlen(arg[iarg+1]) + 1; title1 = new char[n]; strcpy(title1,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title2; int n = strlen(arg[iarg+1]) + 1; title2 = new char[n]; strcpy(title2,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title3; int n = strlen(arg[iarg+1]) + 1; title3 = new char[n]; strcpy(title3,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix ave/spatial command"); + } else error->all(FLERR,"Illegal fix ave/spatial command"); } // setup and error check if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all("Illegal fix ave/spatial command"); + error->all(FLERR,"Illegal fix ave/spatial command"); if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq) - error->all("Illegal fix ave/spatial command"); - if (delta[0] <= 0.0) error->all("Illegal fix ave/spatial command"); + error->all(FLERR,"Illegal fix ave/spatial command"); + if (delta[0] <= 0.0) error->all(FLERR,"Illegal fix ave/spatial command"); if (ndim >= 2 && delta[1] <= 0.0) - error->all("Illegal fix ave/spatial command"); + error->all(FLERR,"Illegal fix ave/spatial command"); if (ndim == 3 && delta[2] <= 0.0) - error->all("Illegal fix ave/spatial command"); + error->all(FLERR,"Illegal fix ave/spatial command"); for (int i = 0; i < nvalues; i++) { if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/spatial does not exist"); + error->all(FLERR,"Compute ID for fix ave/spatial does not exist"); if (modify->compute[icompute]->peratom_flag == 0) - error->all("Fix ave/spatial compute does not " + error->all(FLERR,"Fix ave/spatial compute does not " "calculate per-atom values"); if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Fix ave/spatial compute does not " + error->all(FLERR,"Fix ave/spatial compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Fix ave/spatial compute does not " + error->all(FLERR,"Fix ave/spatial compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Fix ave/spatial compute vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/spatial compute vector is accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/spatial does not exist"); + error->all(FLERR,"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 values"); + error->all(FLERR,"Fix ave/spatial fix does not calculate per-atom values"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Fix ave/spatial fix does not calculate a per-atom vector"); + error->all(FLERR,"Fix ave/spatial fix does not calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Fix ave/spatial fix does not calculate a per-atom array"); + error->all(FLERR,"Fix ave/spatial fix does not calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Fix ave/spatial fix vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/spatial fix vector is accessed out-of-range"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/spatial does not exist"); + error->all(FLERR,"Variable name for fix ave/spatial does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all("Fix ave/spatial variable is not atom-style variable"); + error->all(FLERR,"Fix ave/spatial variable is not atom-style variable"); } } @@ -330,10 +327,10 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : int triclinic = domain->triclinic; if (triclinic == 1 && scaleflag != REDUCED) - error->all("Fix ave/spatial for triclinic boxes requires units reduced"); + error->all(FLERR,"Fix ave/spatial for triclinic boxes requires units reduced"); if (scaleflag == LATTICE && domain->lattice == NULL) - error->all("Use of fix ave/spatial with undefined lattice"); + error->all(FLERR,"Use of fix ave/spatial with undefined lattice"); if (scaleflag == LATTICE) { xscale = domain->lattice->xlattice; @@ -429,7 +426,7 @@ void FixAveSpatial::init() if (regionflag) { iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for fix ave/spatial does not exist"); + error->all(FLERR,"Region ID for fix ave/spatial does not exist"); region = domain->regions[iregion]; } @@ -437,7 +434,7 @@ void FixAveSpatial::init() if (ave == RUNNING || ave == WINDOW) { if (scaleflag != REDUCED && domain->box_change) - error->all("Fix ave/spatial settings invalid with changing box"); + error->all(FLERR,"Fix ave/spatial settings invalid with changing box"); } // set indices and check validity of all computes,fixes,variables @@ -447,22 +444,22 @@ void FixAveSpatial::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for fix ave/spatial does not exist"); + error->all(FLERR,"Compute ID for fix ave/spatial does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for fix ave/spatial does not exist"); + error->all(FLERR,"Fix ID for fix ave/spatial does not exist"); value2index[m] = ifix; if (nevery % modify->fix[ifix]->peratom_freq) - error->all("Fix for fix ave/spatial not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/spatial not computed at compatible time"); } else if (which[m] == VARIABLE) { int ivariable = input->variable->find(ids[m]); if (ivariable < 0) - error->all("Variable name for fix ave/spatial does not exist"); + error->all(FLERR,"Variable name for fix ave/spatial does not exist"); value2index[m] = ivariable; } else value2index[m] = -1; diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index 5addde6258..6d93da8e60 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -43,7 +43,7 @@ enum{SCALAR,VECTOR}; FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix ave/time command"); + if (narg < 7) error->all(FLERR,"Illegal fix ave/time command"); MPI_Comm_rank(world,&me); @@ -98,7 +98,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix ave/time command"); + error->all(FLERR,"Illegal fix ave/time command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -112,7 +112,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : argindex[nvalues] == 0) { int icompute = modify->find_compute(ids[nvalues]); if (icompute < 0) - error->all("Compute ID for fix ave/time does not exist"); + error->all(FLERR,"Compute ID for fix ave/time does not exist"); if (modify->compute[icompute]->array_flag) { int ncols = modify->compute[icompute]->size_array_cols; maxvalues += ncols-1; @@ -132,7 +132,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : argindex[nvalues] == 0) { int ifix = modify->find_fix(ids[nvalues]); if (ifix < 0) - error->all("Fix ID for fix ave/time does not exist"); + error->all(FLERR,"Fix ID for fix ave/time does not exist"); if (modify->fix[ifix]->array_flag) { int ncols = modify->fix[ifix]->size_array_cols; maxvalues += ncols-1; @@ -159,7 +159,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : for (int i = 0; i < nvalues; i++) offcol[i] = 0; for (int i = 0; i < noff; i++) { if (offlist[i] < 1 || offlist[i] > nvalues) - error->all("Invalid fix ave/time off column"); + error->all(FLERR,"Invalid fix ave/time off column"); offcol[offlist[i]-1] = 1; } @@ -167,68 +167,68 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : // for fix inputs, check that fix frequency is acceptable if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all("Illegal fix ave/time command"); + error->all(FLERR,"Illegal fix ave/time command"); if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq) - error->all("Illegal fix ave/time command"); + error->all(FLERR,"Illegal fix ave/time command"); for (int i = 0; i < nvalues; i++) { if (which[i] == COMPUTE && mode == SCALAR) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/time does not exist"); + error->all(FLERR,"Compute ID for fix ave/time does not exist"); if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all("Fix ave/time compute does not calculate a scalar"); + error->all(FLERR,"Fix ave/time compute does not calculate a scalar"); if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all("Fix ave/time compute does not calculate a vector"); + error->all(FLERR,"Fix ave/time compute does not calculate a vector"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all("Fix ave/time compute vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/time compute vector is accessed out-of-range"); } else if (which[i] == COMPUTE && mode == VECTOR) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/time does not exist"); + error->all(FLERR,"Compute ID for fix ave/time does not exist"); if (argindex[i] == 0 && modify->compute[icompute]->vector_flag == 0) - error->all("Fix ave/time compute does not calculate a vector"); + error->all(FLERR,"Fix ave/time compute does not calculate a vector"); if (argindex[i] && modify->compute[icompute]->array_flag == 0) - error->all("Fix ave/time compute does not calculate an array"); + error->all(FLERR,"Fix ave/time compute does not calculate an array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_array_cols) - error->all("Fix ave/time compute array is accessed out-of-range"); + error->all(FLERR,"Fix ave/time compute array is accessed out-of-range"); } else if (which[i] == FIX && mode == SCALAR) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/time does not exist"); + error->all(FLERR,"Fix ID for fix ave/time does not exist"); if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all("Fix ave/time fix does not calculate a scalar"); + error->all(FLERR,"Fix ave/time fix does not calculate a scalar"); if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all("Fix ave/time fix does not calculate a vector"); + error->all(FLERR,"Fix ave/time fix does not calculate a vector"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all("Fix ave/time fix vector is accessed out-of-range"); + error->all(FLERR,"Fix ave/time fix vector is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/time not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/time not computed at compatible time"); } else if (which[i] == FIX && mode == VECTOR) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/time does not exist"); + error->all(FLERR,"Fix ID for fix ave/time does not exist"); if (argindex[i] == 0 && modify->fix[ifix]->vector_flag == 0) - error->all("Fix ave/time fix does not calculate a vector"); + error->all(FLERR,"Fix ave/time fix does not calculate a vector"); if (argindex[i] && modify->fix[ifix]->array_flag == 0) - error->all("Fix ave/time fix does not calculate an array"); + error->all(FLERR,"Fix ave/time fix does not calculate an array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_array_cols) - error->all("Fix ave/time fix array is accessed out-of-range"); + error->all(FLERR,"Fix ave/time fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->global_freq) - error->all("Fix for fix ave/time not computed at compatible time"); + error->all(FLERR,"Fix for fix ave/time not computed at compatible time"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/time does not exist"); + error->all(FLERR,"Variable name for fix ave/time does not exist"); if (input->variable->equalstyle(ivariable) == 0) - error->all("Fix ave/time variable is not equal-style variable"); + error->all(FLERR,"Fix ave/time variable is not equal-style variable"); if (mode == VECTOR) - error->all("Fix ave/time cannot use variable with vector mode"); + error->all(FLERR,"Fix ave/time cannot use variable with vector mode"); } } @@ -250,7 +250,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : } if (i == 0) nrows = length; else if (length != nrows) - error->all("Fix ave/time columns are inconsistent lengths"); + error->all(FLERR,"Fix ave/time columns are inconsistent lengths"); } column = new double[nrows]; @@ -389,11 +389,11 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : else value = fix->extarray; } if (value == -1) - error->all("Fix ave/time cannot set output array " + error->all(FLERR,"Fix ave/time cannot set output array " "intensive/extensive from these inputs"); if (i == 0) extarray = value; else if (value != extarray) - error->all("Fix ave/time cannot set output array " + error->all(FLERR,"Fix ave/time cannot set output array " "intensive/extensive from these inputs"); } } @@ -463,19 +463,19 @@ void FixAveTime::init() if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix ave/time does not exist"); + error->all(FLERR,"Compute ID for fix ave/time does not exist"); value2index[i] = icompute; } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix ave/time does not exist"); + error->all(FLERR,"Fix ID for fix ave/time does not exist"); value2index[i] = ifix; } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix ave/time does not exist"); + error->all(FLERR,"Variable name for fix ave/time does not exist"); value2index[i] = ivariable; } } @@ -833,66 +833,66 @@ void FixAveTime::options(int narg, char **arg) int iarg = 6 + nvalues; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/time command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix ave/time file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/time command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; - else error->all("Illegal fix ave/time command"); + else error->all(FLERR,"Illegal fix ave/time command"); if (ave == WINDOW) { - if (iarg+3 > narg) error->all("Illegal fix ave/time command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/time command"); nwindow = atoi(arg[iarg+2]); - if (nwindow <= 0) error->all("Illegal fix ave/time command"); + if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/time command"); } iarg += 2; if (ave == WINDOW) iarg++; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/time command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); startstep = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"mode") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/time command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR; else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR; - else error->all("Illegal fix ave/time command"); + else error->all(FLERR,"Illegal fix ave/time command"); iarg += 2; } else if (strcmp(arg[iarg],"off") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/time command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); memory->grow(offlist,noff+1,"ave/time:offlist"); offlist[noff++] = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title1; int n = strlen(arg[iarg+1]) + 1; title1 = new char[n]; strcpy(title1,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title2; int n = strlen(arg[iarg+1]) + 1; title2 = new char[n]; strcpy(title2,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command"); delete [] title3; int n = strlen(arg[iarg+1]) + 1; title3 = new char[n]; strcpy(title3,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix ave/time command"); + } else error->all(FLERR,"Illegal fix ave/time command"); } } diff --git a/src/fix_aveforce.cpp b/src/fix_aveforce.cpp index b4fd4f333a..c825e51b38 100644 --- a/src/fix_aveforce.cpp +++ b/src/fix_aveforce.cpp @@ -34,7 +34,7 @@ enum{NONE,CONSTANT,EQUAL}; FixAveForce::FixAveForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix aveforce command"); + if (narg < 6) error->all(FLERR,"Illegal fix aveforce command"); vector_flag = 1; size_vector = 3; @@ -82,15 +82,15 @@ FixAveForce::FixAveForce(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix aveforce command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix aveforce command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) - error->all("Region ID for fix aveforce does not exist"); + error->all(FLERR,"Region ID for fix aveforce does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix aveforce command"); + } else error->all(FLERR,"Illegal fix aveforce command"); } @@ -127,28 +127,28 @@ void FixAveForce::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix aveforce does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; - else error->all("Variable for fix aveforce is invalid style"); + else error->all(FLERR,"Variable for fix aveforce is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix aveforce does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; - else error->all("Variable for fix aveforce is invalid style"); + else error->all(FLERR,"Variable for fix aveforce is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix aveforce does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; - else error->all("Variable for fix aveforce is invalid style"); + else error->all(FLERR,"Variable for fix aveforce is invalid style"); } // set index and check validity of region if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for fix aveforce does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix aveforce does not exist"); } if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL) varflag = EQUAL; diff --git a/src/fix_box_relax.cpp b/src/fix_box_relax.cpp index 7d4d74d08a..09d6f28665 100644 --- a/src/fix_box_relax.cpp +++ b/src/fix_box_relax.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{NONE,XYZ,XY,YZ,XZ}; enum{ISO,ANISO,TRICLINIC}; @@ -45,7 +42,7 @@ enum{ISO,ANISO,TRICLINIC}; FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix box/relax command"); + if (narg < 5) error->all(FLERR,"Illegal fix box/relax command"); scalar_flag = 1; extscalar = 1; @@ -74,7 +71,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"iso") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); pcouple = XYZ; p_target[0] = p_target[1] = p_target[2] = atof(arg[iarg+1]); p_flag[0] = p_flag[1] = p_flag[2] = 1; @@ -84,7 +81,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : } iarg += 2; } else if (strcmp(arg[iarg],"aniso") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); pcouple = NONE; p_target[0] = p_target[1] = p_target[2] = atof(arg[iarg+1]); p_flag[0] = p_flag[1] = p_flag[2] = 1; @@ -94,7 +91,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : } iarg += 2; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); pcouple = NONE; p_target[0] = p_target[1] = p_target[2] = atof(arg[iarg+1]); p_flag[0] = p_flag[1] = p_flag[2] = 1; @@ -107,75 +104,75 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[0] = atof(arg[iarg+1]); p_flag[0] = 1; deviatoric_flag = 1; iarg += 2; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[1] = atof(arg[iarg+1]); p_flag[1] = 1; deviatoric_flag = 1; iarg += 2; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[2] = atof(arg[iarg+1]); p_flag[2] = 1; deviatoric_flag = 1; iarg += 2; if (dimension == 2) - error->all("Invalid fix box/relax command for a 2d simulation"); + error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); } else if (strcmp(arg[iarg],"yz") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[3] = atof(arg[iarg+1]); p_flag[3] = 1; deviatoric_flag = 1; iarg += 2; if (dimension == 2) - error->all("Invalid fix box/relax command for a 2d simulation"); + error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); } else if (strcmp(arg[iarg],"xz") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[4] = atof(arg[iarg+1]); p_flag[4] = 1; deviatoric_flag = 1; iarg += 2; if (dimension == 2) - error->all("Invalid fix box/relax command for a 2d simulation"); + error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); } else if (strcmp(arg[iarg],"xy") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); p_target[5] = atof(arg[iarg+1]); p_flag[5] = 1; deviatoric_flag = 1; iarg += 2; } else if (strcmp(arg[iarg],"couple") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ; else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY; else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ; else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ; else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE; - else error->all("Illegal fix box/relax command"); + else error->all(FLERR,"Illegal fix box/relax command"); iarg += 2; } else if (strcmp(arg[iarg],"dilate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); if (strcmp(arg[iarg+1],"all") == 0) allremap = 1; else if (strcmp(arg[iarg+1],"partial") == 0) allremap = 0; - else error->all("Illegal fix box/relax command"); + else error->all(FLERR,"Illegal fix box/relax command"); iarg += 2; } else if (strcmp(arg[iarg],"vmax") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); vmax = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"nreset") == 0) { - if (iarg+2 > narg) error->all("Illegal fix box/relax command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); nreset_h0 = atoi(arg[iarg+1]); - if (nreset_h0 < 0) error->all("Illegal fix box/relax command"); + if (nreset_h0 < 0) error->all(FLERR,"Illegal fix box/relax command"); iarg += 2; - } else error->all("Illegal fix box/relax command"); + } else error->all(FLERR,"Illegal fix box/relax command"); } if (p_flag[0] || p_flag[1] || p_flag[2]) box_change_size = 1; @@ -185,51 +182,51 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : // error checks if (dimension == 2 && (p_flag[2] || p_flag[3] || p_flag[4])) - error->all("Invalid fix box/relax command for a 2d simulation"); + error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); if (dimension == 2 && (pcouple == YZ || pcouple == XZ)) - error->all("Invalid fix box/relax command for a 2d simulation"); + error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix box/relax command pressure settings"); + error->all(FLERR,"Invalid fix box/relax command pressure settings"); if (pcouple == XYZ && dimension == 3 && p_flag[2] == 0) - error->all("Invalid fix box/relax command pressure settings"); + error->all(FLERR,"Invalid fix box/relax command pressure settings"); if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix box/relax command pressure settings"); + error->all(FLERR,"Invalid fix box/relax command pressure settings"); if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0)) - error->all("Invalid fix box/relax command pressure settings"); + error->all(FLERR,"Invalid fix box/relax command pressure settings"); if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0)) - error->all("Invalid fix box/relax command pressure settings"); + error->all(FLERR,"Invalid fix box/relax command pressure settings"); if (p_flag[0] && domain->xperiodic == 0) - error->all("Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); if (p_flag[1] && domain->yperiodic == 0) - error->all("Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); if (p_flag[2] && domain->zperiodic == 0) - error->all("Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); if (p_flag[3] && domain->zperiodic == 0) - error->all("Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension"); if (p_flag[4] && domain->zperiodic == 0) - error->all("Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension"); if (p_flag[5] && domain->yperiodic == 0) - error->all("Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension"); if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5])) - error->all("Can not specify Pxy/Pxz/Pyz in " + error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in " "fix box/relax with non-triclinic box"); if (pcouple == XYZ && dimension == 3 && (p_target[0] != p_target[1] || p_target[0] != p_target[2])) - error->all("Invalid fix box/relax pressure settings"); + error->all(FLERR,"Invalid fix box/relax pressure settings"); if (pcouple == XYZ && dimension == 2 && p_target[0] != p_target[1]) - error->all("Invalid fix box/relax pressure settings"); + error->all(FLERR,"Invalid fix box/relax pressure settings"); if (pcouple == XY && p_target[0] != p_target[1]) - error->all("Invalid fix box/relax pressure settings"); + error->all(FLERR,"Invalid fix box/relax pressure settings"); if (pcouple == YZ && p_target[1] != p_target[2]) - error->all("Invalid fix box/relax pressure settings"); + error->all(FLERR,"Invalid fix box/relax pressure settings"); if (pcouple == XZ && p_target[0] != p_target[2]) - error->all("Invalid fix box/relax pressure settings"); + error->all(FLERR,"Invalid fix box/relax pressure settings"); - if (vmax <= 0.0) error->all("Illegal fix box/relax command"); + if (vmax <= 0.0) error->all(FLERR,"Illegal fix box/relax command"); // pstyle = TRICLINIC if any off-diagonal term is controlled -> 6 dof // else pstyle = ISO if XYZ coupling or XY coupling in 2d -> 1 dof @@ -314,11 +311,11 @@ void FixBoxRelax::init() int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix box/relax does not exist"); + error->all(FLERR,"Temperature ID for fix box/relax does not exist"); temperature = modify->compute[icompute]; icompute = modify->find_compute(id_press); - if (icompute < 0) error->all("Pressure ID for fix box/relax does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for fix box/relax does not exist"); pressure = modify->compute[icompute]; pv2e = 1.0 / force->nktv2p; @@ -473,7 +470,7 @@ void FixBoxRelax::min_clearstore() void FixBoxRelax::min_pushstore() { if (current_lifo >= MAX_LIFO_DEPTH) { - error->all("Attempt to push beyond stack limit in fix box/relax"); + error->all(FLERR,"Attempt to push beyond stack limit in fix box/relax"); return; } current_lifo++; @@ -487,7 +484,7 @@ void FixBoxRelax::min_pushstore() void FixBoxRelax::min_popstore() { if (current_lifo <= 0) { - error->all("Attempt to pop empty stack in fix box/relax"); + error->all(FLERR,"Attempt to pop empty stack in fix box/relax"); return; } current_lifo--; @@ -611,7 +608,7 @@ void FixBoxRelax::remap() domain->boxlo[i] = currentBoxLo0 + (currentBoxLo0-ctr)*ds[i]/s0[i]; domain->boxhi[i] = currentBoxHi0 + (currentBoxHi0-ctr)*ds[i]/s0[i]; if (domain->boxlo[i] >= domain->boxhi[i]) - error->all("Fix box/relax generated negative box length"); + error->all(FLERR,"Fix box/relax generated negative box length"); } if (pstyle == TRICLINIC) { @@ -680,7 +677,7 @@ void FixBoxRelax::couple() int FixBoxRelax::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -691,24 +688,24 @@ int FixBoxRelax::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for fix modify is not for group all"); + error->warning(FLERR,"Temperature for fix modify is not for group all"); // reset id_temp of pressure to new temperature ID icompute = modify->find_compute(id_press); - if (icompute < 0) error->all("Pressure ID for fix modify does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for fix modify does not exist"); modify->compute[icompute]->reset_extra_compute_fix(id_temp); return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (pflag) { modify->delete_compute(id_press); pflag = 0; @@ -719,11 +716,11 @@ int FixBoxRelax::modify_param(int narg, char **arg) strcpy(id_press,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); return 2; } return 0; diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index 75db867299..039bba40b2 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -43,13 +43,13 @@ enum{NO_REMAP,X_REMAP,V_REMAP}; FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix deform command"); + if (narg < 4) error->all(FLERR,"Illegal fix deform command"); box_change = 1; no_change_box = 1; nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix deform command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix deform command"); // set defaults @@ -72,36 +72,36 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) else if (strcmp(arg[iarg],"y") == 0) index = 1; else if (strcmp(arg[iarg],"z") == 0) index = 2; - if (iarg+2 > narg) error->all("Illegal fix deform command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command"); if (strcmp(arg[iarg+1],"final") == 0) { - if (iarg+4 > narg) error->all("Illegal fix deform command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = FINAL; set[index].flo = atof(arg[iarg+2]); set[index].fhi = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg+1],"delta") == 0) { - if (iarg+4 > narg) error->all("Illegal fix deform command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = DELTA; set[index].dlo = atof(arg[iarg+2]); set[index].dhi = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg+1],"scale") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = SCALE; set[index].scale = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"vel") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = VEL; set[index].vel = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"erate") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = ERATE; set[index].rate = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"trate") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = TRATE; set[index].rate = atof(arg[iarg+2]); iarg += 3; @@ -109,60 +109,60 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) set[index].style = VOLUME; iarg += 2; } else if (strcmp(arg[iarg+1],"wiggle") == 0) { - if (iarg+4 > narg) error->all("Illegal fix deform command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = WIGGLE; set[index].amplitude = atof(arg[iarg+2]); set[index].tperiod = atof(arg[iarg+3]); if (set[index].tperiod <= 0.0) - error->all("Illegal fix deform command"); + error->all(FLERR,"Illegal fix deform command"); iarg += 4; - } else error->all("Illegal fix deform command"); + } else error->all(FLERR,"Illegal fix deform command"); } else if (strcmp(arg[iarg],"xy") == 0 || strcmp(arg[iarg],"xz") == 0 || strcmp(arg[iarg],"yz") == 0) { if (triclinic == 0) - error->all("Fix deform tilt factors require triclinic box"); + error->all(FLERR,"Fix deform tilt factors require triclinic box"); if (strcmp(arg[iarg],"xy") == 0) index = 5; else if (strcmp(arg[iarg],"xz") == 0) index = 4; else if (strcmp(arg[iarg],"yz") == 0) index = 3; - if (iarg+2 > narg) error->all("Illegal fix deform command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command"); if (strcmp(arg[iarg+1],"final") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = FINAL; set[index].ftilt = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"delta") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = DELTA; set[index].dtilt = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"vel") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = VEL; set[index].vel = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"erate") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = ERATE; set[index].rate = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"trate") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deform command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = TRATE; set[index].rate = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg+1],"wiggle") == 0) { - if (iarg+4 > narg) error->all("Illegal fix deform command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command"); set[index].style = WIGGLE; set[index].amplitude = atof(arg[iarg+2]); set[index].tperiod = atof(arg[iarg+3]); if (set[index].tperiod <= 0.0) - error->all("Illegal fix deform command"); + error->all(FLERR,"Illegal fix deform command"); iarg += 4; - } else error->all("Illegal fix deform command"); + } else error->all(FLERR,"Illegal fix deform command"); } else break; } @@ -187,14 +187,14 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if ((set[0].style && domain->xperiodic == 0) || (set[1].style && domain->yperiodic == 0) || (set[2].style && domain->zperiodic == 0)) - error->all("Cannot use fix deform on a non-periodic boundary"); + error->all(FLERR,"Cannot use fix deform on a non-periodic boundary"); if (set[3].style && domain->zperiodic == 0) - error->all("Cannot use fix deform on a 2nd non-periodic boundary"); + error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary"); if (set[4].style && domain->zperiodic == 0) - error->all("Cannot use fix deform on a 2nd non-periodic boundary"); + error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary"); if (set[5].style && domain->yperiodic == 0) - error->all("Cannot use fix deform on a 2nd non-periodic boundary"); + error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary"); // apply scaling to FINAL,DELTA,VEL,WIGGLE since they have distance/vel units @@ -204,7 +204,7 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) set[i].style == VEL || set[i].style == WIGGLE) flag = 1; if (flag && scaleflag && domain->lattice == NULL) - error->all("Use of fix deform with undefined lattice"); + error->all(FLERR,"Use of fix deform with undefined lattice"); double xscale,yscale,zscale; if (flag && scaleflag) { @@ -251,25 +251,25 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (set[other1].style == NONE) { if (set[other2].style == NONE || set[other2].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = ONE_FROM_ONE; set[i].fixed = other1; set[i].dynamic1 = other2; } else if (set[other2].style == NONE) { if (set[other1].style == NONE || set[other1].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = ONE_FROM_ONE; set[i].fixed = other2; set[i].dynamic1 = other1; } else if (set[other1].style == VOLUME) { if (set[other2].style == NONE || set[other2].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = TWO_FROM_ONE; set[i].fixed = other1; set[i].dynamic1 = other2; } else if (set[other2].style == VOLUME) { if (set[other1].style == NONE || set[other1].style == VOLUME) - error->all("Fix deform volume setting is invalid"); + error->all(FLERR,"Fix deform volume setting is invalid"); set[i].substyle = TWO_FROM_ONE; set[i].fixed = other2; set[i].dynamic1 = other1; @@ -347,7 +347,7 @@ void FixDeform::init() int count = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"deform") == 0) count++; - if (count > 1) error->all("More than one fix deform"); + if (count > 1) error->all(FLERR,"More than one fix deform"); // Kspace setting @@ -395,7 +395,7 @@ void FixDeform::init() set[i].hi_stop = set[i].hi_start + 0.5*delt*set[i].rate * (set[i].hi_start-set[i].lo_start); if (set[i].hi_stop <= set[i].lo_stop) - error->all("Final box dimension due to fix deform is < 0.0"); + error->all(FLERR,"Final box dimension due to fix deform is < 0.0"); } else if (set[i].style == TRATE) { set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) - 0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt)); @@ -477,7 +477,7 @@ void FixDeform::init() for (int i = 3; i < 6; i++) if (set[i].style == TRATE && set[i].tilt_start == 0.0) - error->all("Cannot use fix deform trate on a box with zero tilt"); + error->all(FLERR,"Cannot use fix deform trate on a box with zero tilt"); // if yz changes and will cause box flip, then xy cannot be changing // test for WIGGLE is on min/max oscillation limit, not tilt_stop @@ -499,7 +499,7 @@ void FixDeform::init() hi > 0.5*(set[1].hi_stop-set[1].lo_stop)) flag = 1; } if (flag) - error->all("Fix deform is changing yz by too much with changing xy"); + error->all(FLERR,"Fix deform is changing yz by too much with changing xy"); } // set domain->h_rate values for use by domain and other fixes/computes @@ -823,7 +823,7 @@ void FixDeform::end_of_step() void FixDeform::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal fix deform command"); + if (narg < 0) error->all(FLERR,"Illegal fix deform command"); remapflag = X_REMAP; scaleflag = 1; @@ -831,18 +831,18 @@ void FixDeform::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"remap") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deform command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command"); if (strcmp(arg[iarg+1],"x") == 0) remapflag = X_REMAP; else if (strcmp(arg[iarg+1],"v") == 0) remapflag = V_REMAP; else if (strcmp(arg[iarg+1],"none") == 0) remapflag = NO_REMAP; - else error->all("Illegal fix deform command"); + else error->all(FLERR,"Illegal fix deform command"); iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deform command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix deform command"); + else error->all(FLERR,"Illegal fix deform command"); iarg += 2; - } else error->all("Illegal fix deform command"); + } else error->all(FLERR,"Illegal fix deform command"); } } diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp index 357a325942..214856ce37 100644 --- a/src/fix_deposit.cpp +++ b/src/fix_deposit.cpp @@ -36,7 +36,7 @@ using namespace LAMMPS_NS; FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix deposit command"); + if (narg < 7) error->all(FLERR,"Illegal fix deposit command"); restart_global = 1; time_depend = 1; @@ -48,7 +48,7 @@ FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) : nfreq = atoi(arg[5]); seed = atoi(arg[6]); - if (seed <= 0) error->all("Illegal fix deposit command"); + if (seed <= 0) error->all(FLERR,"Illegal fix deposit command"); // set defaults @@ -68,11 +68,11 @@ FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) : // error checks on region and its extent being inside simulation box - if (iregion == -1) error->all("Must specify a region in fix deposit"); + if (iregion == -1) error->all(FLERR,"Must specify a region in fix deposit"); if (domain->regions[iregion]->bboxflag == 0) - error->all("Fix deposit region does not support a bounding box"); + error->all(FLERR,"Fix deposit region does not support a bounding box"); if (domain->regions[iregion]->dynamic_check()) - error->all("Fix deposit region cannot be dynamic"); + error->all(FLERR,"Fix deposit region cannot be dynamic"); xlo = domain->regions[iregion]->extent_xlo; xhi = domain->regions[iregion]->extent_xhi; @@ -85,18 +85,18 @@ FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) : if (xlo < domain->boxlo[0] || xhi > domain->boxhi[0] || ylo < domain->boxlo[1] || yhi > domain->boxhi[1] || zlo < domain->boxlo[2] || zhi > domain->boxhi[2]) - error->all("Deposition region extends outside simulation box"); + error->all(FLERR,"Deposition region extends outside simulation box"); } else { if (xlo < domain->boxlo_bound[0] || xhi > domain->boxhi_bound[0] || ylo < domain->boxlo_bound[1] || yhi > domain->boxhi_bound[1] || zlo < domain->boxlo_bound[2] || zhi > domain->boxhi_bound[2]) - error->all("Deposition region extends outside simulation box"); + error->all(FLERR,"Deposition region extends outside simulation box"); } // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of fix deposit with undefined lattice"); + error->all(FLERR,"Use of fix deposit with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -162,7 +162,7 @@ void FixDeposit::init() // set index and check validity of region iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for fix deposit does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix deposit does not exist"); } /* ---------------------------------------------------------------------- @@ -323,7 +323,7 @@ void FixDeposit::pre_exchange() // warn if not successful b/c too many attempts or no proc owned particle if (!success && comm->me == 0) - error->warning("Particle deposition was unsuccessful",0); + error->warning(FLERR,"Particle deposition was unsuccessful",0); // reset global natoms // set tag # of new particle beyond all previous atoms @@ -356,28 +356,28 @@ void FixDeposit::pre_exchange() void FixDeposit::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal fix indent command"); + if (narg < 0) error->all(FLERR,"Illegal fix indent command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deposit command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) - error->all("Region ID for fix deposit does not exist"); + error->all(FLERR,"Region ID for fix deposit does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"global") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deposit command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deposit command"); globalflag = 1; localflag = 0; lo = atof(arg[iarg+1]); hi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"local") == 0) { - if (iarg+4 > narg) error->all("Illegal fix deposit command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix deposit command"); localflag = 1; globalflag = 0; lo = atof(arg[iarg+1]); @@ -385,40 +385,40 @@ void FixDeposit::options(int narg, char **arg) deltasq = atof(arg[iarg+3])*atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"near") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deposit command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); nearsq = atof(arg[iarg+1])*atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"attempt") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deposit command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); maxattempt = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"rate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deposit command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); rateflag = 1; rate = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"vx") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deposit command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deposit command"); vxlo = atof(arg[iarg+1]); vxhi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"vy") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deposit command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deposit command"); vylo = atof(arg[iarg+1]); vyhi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"vz") == 0) { - if (iarg+3 > narg) error->all("Illegal fix deposit command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix deposit command"); vzlo = atof(arg[iarg+1]); vzhi = atof(arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix deposit command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix deposit command"); + else error->all(FLERR,"Illegal fix deposit command"); iarg += 2; - } else error->all("Illegal fix deposit command"); + } else error->all(FLERR,"Illegal fix deposit command"); } } diff --git a/src/fix_drag.cpp b/src/fix_drag.cpp index 357495bd67..51e744aada 100644 --- a/src/fix_drag.cpp +++ b/src/fix_drag.cpp @@ -28,7 +28,7 @@ using namespace LAMMPS_NS; FixDrag::FixDrag(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 8) error->all("Illegal fix drag command"); + if (narg != 8) error->all(FLERR,"Illegal fix drag command"); vector_flag = 1; size_vector = 3; diff --git a/src/fix_dt_reset.cpp b/src/fix_dt_reset.cpp index 8991a879e5..758c8b32a5 100644 --- a/src/fix_dt_reset.cpp +++ b/src/fix_dt_reset.cpp @@ -33,15 +33,12 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix dt/reset command"); + if (narg < 7) error->all(FLERR,"Illegal fix dt/reset command"); time_depend = 1; scalar_flag = 1; @@ -52,7 +49,7 @@ FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) : extvector = 0; nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix dt/reset command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix dt/reset command"); minbound = maxbound = 1; tmin = tmax = 0.0; @@ -62,29 +59,29 @@ FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) : else tmax = atof(arg[5]); xmax = atof(arg[6]); - if (minbound && tmin < 0.0) error->all("Illegal fix dt/reset command"); - if (maxbound && tmax < 0.0) error->all("Illegal fix dt/reset command"); + if (minbound && tmin < 0.0) error->all(FLERR,"Illegal fix dt/reset command"); + if (maxbound && tmax < 0.0) error->all(FLERR,"Illegal fix dt/reset command"); if (minbound && maxbound && tmin >= tmax) - error->all("Illegal fix dt/reset command"); - if (xmax <= 0.0) error->all("Illegal fix dt/reset command"); + error->all(FLERR,"Illegal fix dt/reset command"); + if (xmax <= 0.0) error->all(FLERR,"Illegal fix dt/reset command"); int scaleflag = 1; int iarg = 7; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix dt/reset command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix dt/reset command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix dt/reset command"); + else error->all(FLERR,"Illegal fix dt/reset command"); iarg += 2; - } else error->all("Illegal fix dt/reset command"); + } else error->all(FLERR,"Illegal fix dt/reset command"); } // setup scaling, based on xlattice parameter if (scaleflag && domain->lattice == NULL) - error->all("Use of fix dt/reset with undefined lattice"); + error->all(FLERR,"Use of fix dt/reset with undefined lattice"); if (scaleflag) xmax *= domain->lattice->xlattice; // initializations @@ -116,7 +113,7 @@ void FixDtReset::init() for (int i = 0; i < output->ndump; i++) if ((strcmp(output->dump[i]->style,"dcd") == 0 || strcmp(output->dump[i]->style,"xtc") == 0) && comm->me == 0) - error->warning("Dump dcd/xtc timestamp may be wrong with fix dt/reset"); + error->warning(FLERR,"Dump dcd/xtc timestamp may be wrong with fix dt/reset"); ftm2v = force->ftm2v; } diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index 31c7ba147a..42bc2efc94 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -38,7 +38,7 @@ enum{CONSTANT,EQUAL,ATOM}; FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix efield command"); + if (narg != 6) error->all(FLERR,"Illegal fix efield command"); qe2f = force->qe2f; xstr = ystr = zstr = NULL; @@ -98,30 +98,30 @@ int FixEfield::setmask() void FixEfield::init() { - if (!atom->q_flag) error->all("Fix efield requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR,"Fix efield requires atom attribute q"); // check variables if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix efield does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix efield does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; - else error->all("Variable for fix efield is invalid style"); + else error->all(FLERR,"Variable for fix efield is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix efield does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix efield does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; - else error->all("Variable for fix efield is invalid style"); + else error->all(FLERR,"Variable for fix efield is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix efield does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix efield does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; - else error->all("Variable for fix efield is invalid style"); + else error->all(FLERR,"Variable for fix efield is invalid style"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) diff --git a/src/fix_enforce2d.cpp b/src/fix_enforce2d.cpp index c08c1ecdce..ad7ef9f615 100644 --- a/src/fix_enforce2d.cpp +++ b/src/fix_enforce2d.cpp @@ -26,7 +26,7 @@ using namespace LAMMPS_NS; FixEnforce2D::FixEnforce2D(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix enforce2d command"); + if (narg != 3) error->all(FLERR,"Illegal fix enforce2d command"); } /* ---------------------------------------------------------------------- */ @@ -45,7 +45,7 @@ int FixEnforce2D::setmask() void FixEnforce2D::init() { if (domain->dimension == 3) - error->all("Cannot use fix enforce2d with 3d simulation"); + error->all(FLERR,"Cannot use fix enforce2d with 3d simulation"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_evaporate.cpp b/src/fix_evaporate.cpp index 4e8c779561..a0446c4675 100644 --- a/src/fix_evaporate.cpp +++ b/src/fix_evaporate.cpp @@ -30,15 +30,12 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixEvaporate::FixEvaporate(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix evaporate command"); + if (narg < 7) error->all(FLERR,"Illegal fix evaporate command"); scalar_flag = 1; global_freq = 1; @@ -52,9 +49,9 @@ FixEvaporate::FixEvaporate(LAMMPS *lmp, int narg, char **arg) : strcpy(idregion,arg[5]); int seed = atoi(arg[6]); - if (nevery <= 0 || nflux <= 0) error->all("Illegal fix evaporate command"); - if (iregion == -1) error->all("Region ID for fix evaporate does not exist"); - if (seed <= 0) error->all("Illegal fix evaporate command"); + if (nevery <= 0 || nflux <= 0) error->all(FLERR,"Illegal fix evaporate command"); + if (iregion == -1) error->all(FLERR,"Region ID for fix evaporate does not exist"); + if (seed <= 0) error->all(FLERR,"Illegal fix evaporate command"); // random number generator, same for all procs @@ -67,12 +64,12 @@ FixEvaporate::FixEvaporate(LAMMPS *lmp, int narg, char **arg) : int iarg = 7; while (iarg < narg) { if (strcmp(arg[iarg],"molecule") == 0) { - if (iarg+2 > narg) error->all("Illegal fix evaporate command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix evaporate command"); if (strcmp(arg[iarg+1],"no") == 0) molflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) molflag = 1; - else error->all("Illegal fix evaporate command"); + else error->all(FLERR,"Illegal fix evaporate command"); iarg += 2; - } else error->all("Illegal fix evaporate command"); + } else error->all(FLERR,"Illegal fix evaporate command"); } // set up reneighboring @@ -113,7 +110,7 @@ void FixEvaporate::init() iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for fix evaporate does not exist"); + error->all(FLERR,"Region ID for fix evaporate does not exist"); // check that no deletable atoms are in atom->firstgroup // deleting such an atom would not leave firstgroup atoms first @@ -131,7 +128,7 @@ void FixEvaporate::init() MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall) - error->all("Cannot evaporate atoms in atom_modify first group"); + error->all(FLERR,"Cannot evaporate atoms in atom_modify first group"); } // if molflag not set, warn if any deletable atom has a mol ID @@ -147,12 +144,12 @@ void FixEvaporate::init() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && comm->me == 0) - error-> - warning("Fix evaporate may delete atom with non-zero molecule ID"); + error->warning(FLERR, + "Fix evaporate may delete atom with non-zero molecule ID"); } if (molflag && atom->molecule_flag == 0) - error->all("Fix evaporate molecule requires atom attribute molecule"); + error->all(FLERR,"Fix evaporate molecule requires atom attribute molecule"); } /* ---------------------------------------------------------------------- diff --git a/src/fix_external.cpp b/src/fix_external.cpp index 449a6d07c9..dd92847cf0 100644 --- a/src/fix_external.cpp +++ b/src/fix_external.cpp @@ -26,7 +26,7 @@ using namespace LAMMPS_NS; FixExternal::FixExternal(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix external command"); + if (narg != 3) error->all(FLERR,"Illegal fix external command"); callback = NULL; @@ -55,7 +55,7 @@ int FixExternal::setmask() void FixExternal::init() { - if (callback == NULL) error->all("Fix external callback function not set"); + if (callback == NULL) error->all(FLERR,"Fix external callback function not set"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_gravity.cpp b/src/fix_gravity.cpp index e3d2ae8ead..09a2e2c7f1 100644 --- a/src/fix_gravity.cpp +++ b/src/fix_gravity.cpp @@ -31,7 +31,7 @@ enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix gravity command"); + if (narg < 5) error->all(FLERR,"Illegal fix gravity command"); time_depend = 1; scalar_flag = 1; @@ -41,29 +41,29 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) : magnitude = atof(arg[3]); if (strcmp(arg[4],"chute") == 0) { - if (narg != 6) error->all("Illegal fix gravity command"); + if (narg != 6) error->all(FLERR,"Illegal fix gravity command"); style = CHUTE; phi = 0.0; theta = 180.0 - atof(arg[5]); } else if (strcmp(arg[4],"spherical") == 0) { - if (narg != 7) error->all("Illegal fix gravity command"); + if (narg != 7) error->all(FLERR,"Illegal fix gravity command"); style = SPHERICAL; phi = atof(arg[5]); theta = atof(arg[6]); } else if (strcmp(arg[4],"gradient") == 0) { - if (narg != 9) error->all("Illegal fix gravity command"); + if (narg != 9) error->all(FLERR,"Illegal fix gravity command"); style = GRADIENT; phi = atof(arg[5]); theta = atof(arg[6]); phigrad = atof(arg[7]); thetagrad = atof(arg[8]); } else if (strcmp(arg[4],"vector") == 0) { - if (narg != 8) error->all("Illegal fix gravity command"); + if (narg != 8) error->all(FLERR,"Illegal fix gravity command"); style = VECTOR; xdir = atof(arg[5]); ydir = atof(arg[6]); zdir = atof(arg[7]); - } else error->all("Illegal fix gravity command"); + } else error->all(FLERR,"Illegal fix gravity command"); double PI = 4.0*atan(1.0); degree2rad = PI/180.0; diff --git a/src/fix_heat.cpp b/src/fix_heat.cpp index 450d0bb841..45bd030cc2 100644 --- a/src/fix_heat.cpp +++ b/src/fix_heat.cpp @@ -33,14 +33,14 @@ using namespace LAMMPS_NS; FixHeat::FixHeat(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix heat command"); + if (narg < 4) error->all(FLERR,"Illegal fix heat command"); scalar_flag = 1; global_freq = 1; extscalar = 0; nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix heat command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix heat command"); heat_input = atof(arg[4]); @@ -52,14 +52,14 @@ FixHeat::FixHeat(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) int iarg = 5; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix heat command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix heat command"); iregion = domain->find_region(arg[iarg+1]); - if (iregion == -1) error->all("Region ID for fix heat does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix heat does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix heat command"); + } else error->all(FLERR,"Illegal fix heat command"); } scale = 1.0; @@ -89,12 +89,12 @@ void FixHeat::init() if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for fix heat does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix heat does not exist"); } // cannot have 0 atoms in group - if (group->count(igroup) == 0) error->all("Fix heat group has no atoms"); + if (group->count(igroup) == 0) error->all(FLERR,"Fix heat group has no atoms"); masstotal = group->mass(igroup); } @@ -113,7 +113,7 @@ void FixHeat::end_of_step() group->vcm(igroup,masstotal,vcm); } else { masstotal = group->mass(igroup,iregion); - if (masstotal == 0.0) error->all("Fix heat group has no atoms"); + if (masstotal == 0.0) error->all(FLERR,"Fix heat group has no atoms"); heat = heat_input*nevery*update->dt*force->ftm2v; ke = group->ke(igroup,iregion)*force->ftm2v; group->vcm(igroup,masstotal,vcm,iregion); @@ -121,7 +121,7 @@ void FixHeat::end_of_step() double vcmsq = vcm[0]*vcm[0] + vcm[1]*vcm[1] + vcm[2]*vcm[2]; double escale = (ke + heat - 0.5*vcmsq*masstotal)/(ke - 0.5*vcmsq*masstotal); - if (escale < 0.0) error->all("Fix heat kinetic energy went negative"); + if (escale < 0.0) error->all(FLERR,"Fix heat kinetic energy went negative"); scale = sqrt(escale); vsub[0] = (scale-1.0) * vcm[0]; diff --git a/src/fix_indent.cpp b/src/fix_indent.cpp index dd6f7490ee..48f72ac048 100644 --- a/src/fix_indent.cpp +++ b/src/fix_indent.cpp @@ -40,7 +40,7 @@ enum{INSIDE,OUTSIDE}; FixIndent::FixIndent(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix indent command"); + if (narg < 4) error->all(FLERR,"Illegal fix indent command"); scalar_flag = 1; vector_flag = 1; @@ -59,7 +59,7 @@ FixIndent::FixIndent(LAMMPS *lmp, int narg, char **arg) : // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of fix indent with undefined lattice"); + error->all(FLERR,"Use of fix indent with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -80,7 +80,7 @@ FixIndent::FixIndent(LAMMPS *lmp, int narg, char **arg) : if (cdim == 0 && !pstr) pvalue *= xscale; else if (cdim == 1 && !pstr) pvalue *= yscale; else if (cdim == 2 && !pstr) pvalue *= zscale; - } else error->all("Illegal fix indent command"); + } else error->all(FLERR,"Illegal fix indent command"); varflag = 0; if (xstr || ystr || zstr || rstr || pstr) varflag = 1; @@ -118,33 +118,33 @@ void FixIndent::init() { if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix indent does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix indent does not exist"); if (!input->variable->equalstyle(xvar)) - error->all("Variable for fix indent is invalid style"); + error->all(FLERR,"Variable for fix indent is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix indent does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix indent does not exist"); if (!input->variable->equalstyle(yvar)) - error->all("Variable for fix indent is not equal style"); + error->all(FLERR,"Variable for fix indent is not equal style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix indent does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix indent does not exist"); if (!input->variable->equalstyle(zvar)) - error->all("Variable for fix indent is not equal style"); + error->all(FLERR,"Variable for fix indent is not equal style"); } if (rstr) { rvar = input->variable->find(rstr); - if (rvar < 0) error->all("Variable name for fix indent does not exist"); + if (rvar < 0) error->all(FLERR,"Variable name for fix indent does not exist"); if (!input->variable->equalstyle(rvar)) - error->all("Variable for fix indent is not equal style"); + error->all(FLERR,"Variable for fix indent is not equal style"); } if (pstr) { pvar = input->variable->find(pstr); - if (pvar < 0) error->all("Variable name for fix indent does not exist"); + if (pvar < 0) error->all(FLERR,"Variable name for fix indent does not exist"); if (!input->variable->equalstyle(pvar)) - error->all("Variable for fix indent is not equal style"); + error->all(FLERR,"Variable for fix indent is not equal style"); } if (strstr(update->integrate_style,"respa")) @@ -396,7 +396,7 @@ double FixIndent::compute_vector(int n) void FixIndent::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal fix indent command"); + if (narg < 0) error->all(FLERR,"Illegal fix indent command"); istyle = NONE; xstr = ystr = zstr = rstr = pstr = NULL; @@ -407,7 +407,7 @@ void FixIndent::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"sphere") == 0) { - if (iarg+5 > narg) error->all("Illegal fix indent command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix indent command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { int n = strlen(&arg[iarg+1][2]) + 1; @@ -434,7 +434,7 @@ void FixIndent::options(int narg, char **arg) iarg += 5; } else if (strcmp(arg[iarg],"cylinder") == 0) { - if (iarg+5 > narg) error->all("Illegal fix indent command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix indent command"); if (strcmp(arg[iarg+1],"x") == 0) { cdim = 0; @@ -472,7 +472,7 @@ void FixIndent::options(int narg, char **arg) ystr = new char[n]; strcpy(ystr,&arg[iarg+3][2]); } else yvalue = atof(arg[iarg+3]); - } else error->all("Illegal fix indent command"); + } else error->all(FLERR,"Illegal fix indent command"); if (strstr(arg[iarg+4],"v_") == arg[iarg+4]) { int n = strlen(&arg[iarg+4][2]) + 1; @@ -484,11 +484,11 @@ void FixIndent::options(int narg, char **arg) iarg += 5; } else if (strcmp(arg[iarg],"plane") == 0) { - if (iarg+4 > narg) error->all("Illegal fix indent command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix indent command"); if (strcmp(arg[iarg+1],"x") == 0) cdim = 0; else if (strcmp(arg[iarg+1],"y") == 0) cdim = 1; else if (strcmp(arg[iarg+1],"z") == 0) cdim = 2; - else error->all("Illegal fix indent command"); + else error->all(FLERR,"Illegal fix indent command"); if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; @@ -498,23 +498,23 @@ void FixIndent::options(int narg, char **arg) if (strcmp(arg[iarg+3],"lo") == 0) planeside = -1; else if (strcmp(arg[iarg+3],"hi") == 0) planeside = 1; - else error->all("Illegal fix indent command"); + else error->all(FLERR,"Illegal fix indent command"); istyle = PLANE; iarg += 4; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix indent command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix indent command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix indent command"); + else error->all(FLERR,"Illegal fix indent command"); iarg += 2; } else if (strcmp(arg[iarg],"side") == 0) { - if (iarg+2 > narg) error->all("Illegal fix indent command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix indent command"); if (strcmp(arg[iarg+1],"in") == 0) side = INSIDE; else if (strcmp(arg[iarg+1],"out") == 0) side = OUTSIDE; - else error->all("Illegal fix indent command"); + else error->all(FLERR,"Illegal fix indent command"); iarg += 2; - } else error->all("Illegal fix indent command"); + } else error->all(FLERR,"Illegal fix indent command"); } } diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp index e887928993..d7683d7dee 100644 --- a/src/fix_langevin.cpp +++ b/src/fix_langevin.cpp @@ -48,7 +48,7 @@ enum{NOBIAS,BIAS}; FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix langevin command"); + if (narg < 7) error->all(FLERR,"Illegal fix langevin command"); scalar_flag = 1; global_freq = 1; @@ -60,8 +60,8 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) : t_period = atof(arg[5]); int seed = atoi(arg[6]); - if (t_period <= 0.0) error->all("Fix langevin period must be > 0.0"); - if (seed <= 0) error->all("Illegal fix langevin command"); + if (t_period <= 0.0) error->all(FLERR,"Fix langevin period must be > 0.0"); + if (seed <= 0) error->all(FLERR,"Illegal fix langevin command"); // initialize Marsaglia RNG with processor-unique seed @@ -83,38 +83,38 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) : int iarg = 7; while (iarg < narg) { if (strcmp(arg[iarg],"angmom") == 0) { - if (iarg+2 > narg) error->all("Illegal fix langevin command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command"); if (strcmp(arg[iarg+1],"no") == 0) aflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) aflag = 1; - else error->all("Illegal fix langevin command"); + else error->all(FLERR,"Illegal fix langevin command"); iarg += 2; } else if (strcmp(arg[iarg],"omega") == 0) { - if (iarg+2 > narg) error->all("Illegal fix langevin command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command"); if (strcmp(arg[iarg+1],"no") == 0) oflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) oflag = 1; - else error->all("Illegal fix langevin command"); + else error->all(FLERR,"Illegal fix langevin command"); iarg += 2; } else if (strcmp(arg[iarg],"scale") == 0) { - if (iarg+3 > narg) error->all("Illegal fix langevin command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix langevin command"); int itype = atoi(arg[iarg+1]); double scale = atof(arg[iarg+2]); if (itype <= 0 || itype > atom->ntypes) - error->all("Illegal fix langevin command"); + error->all(FLERR,"Illegal fix langevin command"); ratio[itype] = scale; iarg += 3; } else if (strcmp(arg[iarg],"tally") == 0) { - if (iarg+2 > narg) error->all("Illegal fix langevin command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command"); if (strcmp(arg[iarg+1],"no") == 0) tally = 0; else if (strcmp(arg[iarg+1],"yes") == 0) tally = 1; - else error->all("Illegal fix langevin command"); + else error->all(FLERR,"Illegal fix langevin command"); iarg += 2; } else if (strcmp(arg[iarg],"zero") == 0) { - if (iarg+2 > narg) error->all("Illegal fix langevin command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command"); if (strcmp(arg[iarg+1],"no") == 0) zeroflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) zeroflag = 1; - else error->all("Illegal fix langevin command"); + else error->all(FLERR,"Illegal fix langevin command"); iarg += 2; - } else error->all("Illegal fix langevin command"); + } else error->all(FLERR,"Illegal fix langevin command"); } // error check @@ -122,7 +122,7 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) : if (aflag) { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) - error->all("Fix langevin angmom requires atom style ellipsoid"); + error->all(FLERR,"Fix langevin angmom requires atom style ellipsoid"); } // set temperature = NULL, user can override via fix_modify if wants bias @@ -167,9 +167,9 @@ int FixLangevin::setmask() void FixLangevin::init() { if (oflag && !atom->sphere_flag) - error->all("Fix langevin omega require atom style sphere"); + error->all(FLERR,"Fix langevin omega require atom style sphere"); if (aflag && !atom->ellipsoid_flag) - error->all("Fix langevin angmom require atom style ellipsoid"); + error->all(FLERR,"Fix langevin angmom require atom style ellipsoid"); // if oflag or aflag set, check that all group particles are finite-size @@ -181,7 +181,7 @@ void FixLangevin::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (radius[i] == 0.0) - error->one("Fix langevin omega requires extended particles"); + error->one(FLERR,"Fix langevin omega requires extended particles"); } if (aflag) { @@ -192,7 +192,7 @@ void FixLangevin::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) - error->one("Fix langevin angmom requires extended particles"); + error->one(FLERR,"Fix langevin angmom requires extended particles"); } // set force prefactors @@ -283,7 +283,7 @@ void FixLangevin::post_force_no_tally() if (zeroflag) { count = group->count(igroup); if (count == 0) - error->all("Cannot zero Langevin force of 0 atoms"); + error->all(FLERR,"Cannot zero Langevin force of 0 atoms"); } if (rmass) { @@ -656,20 +656,20 @@ void FixLangevin::reset_dt() int FixLangevin::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); delete [] id_temp; int n = strlen(arg[1]) + 1; id_temp = new char[n]; strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/fix_lineforce.cpp b/src/fix_lineforce.cpp index 9f3f6b241b..f56c28146a 100644 --- a/src/fix_lineforce.cpp +++ b/src/fix_lineforce.cpp @@ -27,13 +27,13 @@ using namespace LAMMPS_NS; FixLineForce::FixLineForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix lineforce command"); + if (narg != 6) error->all(FLERR,"Illegal fix lineforce command"); xdir = atof(arg[3]); ydir = atof(arg[4]); zdir = atof(arg[5]); double len = sqrt(xdir*xdir + ydir*ydir + zdir*zdir); - if (len == 0.0) error->all("Illegal fix lineforce command"); + if (len == 0.0) error->all(FLERR,"Illegal fix lineforce command"); xdir /= len; ydir /= len; diff --git a/src/fix_momentum.cpp b/src/fix_momentum.cpp index 400f394c93..8fb7f3ae02 100644 --- a/src/fix_momentum.cpp +++ b/src/fix_momentum.cpp @@ -30,16 +30,16 @@ using namespace LAMMPS_NS; FixMomentum::FixMomentum(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix momentum command"); + if (narg < 4) error->all(FLERR,"Illegal fix momentum command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix momentum command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix momentum command"); linear = angular = 0; int iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"linear") == 0) { - if (iarg+4 > narg) error->all("Illegal fix momentum command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix momentum command"); linear = 1; xflag = atoi(arg[iarg+1]); yflag = atoi(arg[iarg+2]); @@ -48,20 +48,20 @@ FixMomentum::FixMomentum(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"angular") == 0) { angular = 1; iarg += 1; - } else error->all("Illegal fix momentum command"); + } else error->all(FLERR,"Illegal fix momentum command"); } if (linear == 0 && angular == 0) - error->all("Illegal fix momentum command"); + error->all(FLERR,"Illegal fix momentum command"); if (linear) if (xflag < 0 || xflag > 1 || yflag < 0 || yflag > 1 || - zflag < 0 || zflag > 1) error->all("Illegal fix momentum command"); + zflag < 0 || zflag > 1) error->all(FLERR,"Illegal fix momentum command"); // cannot have 0 atoms in group if (group->count(igroup) == 0) - error->all("Fix momentum group has no atoms"); + error->all(FLERR,"Fix momentum group has no atoms"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_move.cpp b/src/fix_move.cpp index bb886f8ec0..afd087772e 100644 --- a/src/fix_move.cpp +++ b/src/fix_move.cpp @@ -39,7 +39,7 @@ enum{EQUAL,ATOM}; FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix move command"); + if (narg < 4) error->all(FLERR,"Illegal fix move command"); restart_global = 1; restart_peratom = 1; @@ -57,7 +57,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : vxvarstr = vyvarstr = vzvarstr = NULL; if (strcmp(arg[3],"linear") == 0) { - if (narg < 7) error->all("Illegal fix move command"); + if (narg < 7) error->all(FLERR,"Illegal fix move command"); iarg = 7; mstyle = LINEAR; if (strcmp(arg[4],"NULL") == 0) vxflag = 0; @@ -77,7 +77,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : } } else if (strcmp(arg[3],"wiggle") == 0) { - if (narg < 8) error->all("Illegal fix move command"); + if (narg < 8) error->all(FLERR,"Illegal fix move command"); iarg = 8; mstyle = WIGGLE; if (strcmp(arg[4],"NULL") == 0) axflag = 0; @@ -98,7 +98,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : period = atof(arg[7]); } else if (strcmp(arg[3],"rotate") == 0) { - if (narg < 11) error->all("Illegal fix move command"); + if (narg < 11) error->all(FLERR,"Illegal fix move command"); iarg = 11; mstyle = ROTATE; point[0] = atof(arg[4]); @@ -110,7 +110,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : period = atof(arg[10]); } else if (strcmp(arg[3],"variable") == 0) { - if (narg < 10) error->all("Illegal fix move command"); + if (narg < 10) error->all(FLERR,"Illegal fix move command"); iarg = 10; mstyle = VARIABLE; if (strcmp(arg[4],"NULL") == 0) xvarstr = NULL; @@ -118,39 +118,39 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : int n = strlen(&arg[4][2]) + 1; xvarstr = new char[n]; strcpy(xvarstr,&arg[4][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[5],"NULL") == 0) yvarstr = NULL; else if (strstr(arg[5],"v_") == arg[5]) { int n = strlen(&arg[5][2]) + 1; yvarstr = new char[n]; strcpy(yvarstr,&arg[5][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[6],"NULL") == 0) zvarstr = NULL; else if (strstr(arg[6],"v_") == arg[6]) { int n = strlen(&arg[6][2]) + 1; zvarstr = new char[n]; strcpy(zvarstr,&arg[6][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[7],"NULL") == 0) vxvarstr = NULL; else if (strstr(arg[7],"v_") == arg[7]) { int n = strlen(&arg[7][2]) + 1; vxvarstr = new char[n]; strcpy(vxvarstr,&arg[7][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[8],"NULL") == 0) vyvarstr = NULL; else if (strstr(arg[8],"v_") == arg[8]) { int n = strlen(&arg[8][2]) + 1; vyvarstr = new char[n]; strcpy(vyvarstr,&arg[8][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[9],"NULL") == 0) vzvarstr = NULL; else if (strstr(arg[9],"v_") == arg[9]) { int n = strlen(&arg[9][2]) + 1; vzvarstr = new char[n]; strcpy(vzvarstr,&arg[9][2]); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); // optional args @@ -158,38 +158,38 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix move command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix move command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix move command"); + else error->all(FLERR,"Illegal fix move command"); iarg += 2; - } else error->all("Illegal fix move command"); + } else error->all(FLERR,"Illegal fix move command"); } // error checks and warnings if (domain->dimension == 2) { if (mstyle == LINEAR && vzflag && vz != 0.0) - error->all("Fix move cannot set linear z motion for 2d problem"); + error->all(FLERR,"Fix move cannot set linear z motion for 2d problem"); if (mstyle == WIGGLE && azflag && az != 0.0) - error->all("Fix move cannot set wiggle z motion for 2d problem"); + error->all(FLERR,"Fix move cannot set wiggle z motion for 2d problem"); if (mstyle == ROTATE && (axis[0] != 0.0 || axis[1] != 0.0)) - error->all("Fix move cannot rotate aroung non z-axis for 2d problem"); + error->all(FLERR,"Fix move cannot rotate aroung non z-axis for 2d problem"); if (mstyle == VARIABLE && (zvarstr || vzvarstr)) - error->all("Fix move cannot define z or vz variable for 2d problem"); + error->all(FLERR,"Fix move cannot define z or vz variable for 2d problem"); } if (atom->angmom_flag && comm->me == 0) - error->warning("Fix move does not update angular momentum"); + error->warning(FLERR,"Fix move does not update angular momentum"); if (atom->ellipsoid_flag && comm->me == 0) - error->warning("Fix move does not update quaternions"); + error->warning(FLERR,"Fix move does not update quaternions"); // setup scaling and apply scaling factors to velocity & amplitude if ((mstyle == LINEAR || mstyle == WIGGLE || mstyle == ROTATE) && scaleflag) { if (domain->lattice == NULL) - error->all("Use of fix move with undefined lattice"); + error->all(FLERR,"Use of fix move with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -226,7 +226,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : if (mstyle == ROTATE) { double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (len == 0.0) - error->all("Fix move cannot have 0 length rotation vector"); + error->all(FLERR,"Fix move cannot have 0 length rotation vector"); runit[0] = axis[0]/len; runit[1] = axis[1]/len; runit[2] = axis[2]/len; @@ -310,45 +310,45 @@ void FixMove::init() if (mstyle == VARIABLE) { if (xvarstr) { xvar = input->variable->find(xvarstr); - if (xvar < 0) error->all("Variable name for fix move does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(xvar)) xvarstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } if (yvarstr) { yvar = input->variable->find(yvarstr); - if (yvar < 0) error->all("Variable name for fix move does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(yvar)) yvarstyle = EQUAL; else if (input->variable->atomstyle(yvar)) yvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } if (zvarstr) { zvar = input->variable->find(zvarstr); - if (zvar < 0) error->all("Variable name for fix move does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(zvar)) zvarstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } if (vxvarstr) { vxvar = input->variable->find(vxvarstr); - if (vxvar < 0) error->all("Variable name for fix move does not exist"); + if (vxvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(vxvar)) vxvarstyle = EQUAL; else if (input->variable->atomstyle(vxvar)) vxvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } if (vyvarstr) { vyvar = input->variable->find(vyvarstr); - if (vyvar < 0) error->all("Variable name for fix move does not exist"); + if (vyvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(vyvar)) vyvarstyle = EQUAL; else if (input->variable->atomstyle(vyvar)) vyvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } if (vzvarstr) { vzvar = input->variable->find(vzvarstr); - if (vzvar < 0) error->all("Variable name for fix move does not exist"); + if (vzvar < 0) error->all(FLERR,"Variable name for fix move does not exist"); if (input->variable->equalstyle(vzvar)) vzvarstyle = EQUAL; else if (input->variable->atomstyle(vzvar)) vzvarstyle = ATOM; - else error->all("Variable for fix move is invalid style"); + else error->all(FLERR,"Variable for fix move is invalid style"); } displaceflag = velocityflag = 0; @@ -883,7 +883,7 @@ void FixMove::set_arrays(int i) // backup particle to time_origin if (mstyle == VARIABLE) - error->all("Cannot add atoms to fix move variable"); + error->all(FLERR,"Cannot add atoms to fix move variable"); domain->unmap(x[i],image[i],xoriginal[i]); double delta = (update->ntimestep - time_origin) * update->dt; @@ -1005,5 +1005,5 @@ int FixMove::size_restart(int nlocal) void FixMove::reset_dt() { - error->all("Resetting timestep is not allowed with fix move"); + error->all(FLERR,"Resetting timestep is not allowed with fix move"); } diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp index 2854893057..2bf3df8a89 100644 --- a/src/fix_nh.cpp +++ b/src/fix_nh.cpp @@ -39,9 +39,6 @@ using namespace LAMMPS_NS; #define DELTAFLIP 0.1 #define TILTMAX 1.5 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{NOBIAS,BIAS}; enum{NONE,XYZ,XY,YZ,XZ}; enum{ISO,ANISO,TRICLINIC}; @@ -52,7 +49,7 @@ enum{ISO,ANISO,TRICLINIC}; FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix nvt/npt/nph command"); + if (narg < 4) error->all(FLERR,"Illegal fix nvt/npt/nph command"); restart_global = 1; time_integrate = 1; @@ -106,17 +103,17 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) while (iarg < narg) { if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); tstat_flag = 1; t_start = atof(arg[iarg+1]); t_stop = atof(arg[iarg+2]); t_period = atof(arg[iarg+3]); if (t_start < 0.0 || t_stop <= 0.0) - error->all("Target temperature for fix nvt/npt/nph cannot be 0.0"); + error->all(FLERR,"Target temperature for fix nvt/npt/nph cannot be 0.0"); iarg += 4; } else if (strcmp(arg[iarg],"iso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = XYZ; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -128,7 +125,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } iarg += 4; } else if (strcmp(arg[iarg],"aniso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = NONE; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -140,7 +137,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } iarg += 4; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); pcouple = NONE; scalexy = scalexz = scaleyz = 0; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); @@ -161,7 +158,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) } iarg += 4; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[0] = atof(arg[iarg+1]); p_stop[0] = atof(arg[iarg+2]); p_period[0] = atof(arg[iarg+3]); @@ -169,7 +166,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[1] = atof(arg[iarg+1]); p_stop[1] = atof(arg[iarg+2]); p_period[1] = atof(arg[iarg+3]); @@ -177,7 +174,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[2] = atof(arg[iarg+1]); p_stop[2] = atof(arg[iarg+2]); p_period[2] = atof(arg[iarg+3]); @@ -185,10 +182,10 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"yz") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); scaleyz = 0; p_start[3] = atof(arg[iarg+1]); p_stop[3] = atof(arg[iarg+2]); @@ -197,9 +194,9 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"xz") == 0) { - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); scalexz = 0; p_start[4] = atof(arg[iarg+1]); p_stop[4] = atof(arg[iarg+2]); @@ -208,10 +205,10 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) deviatoric_flag = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); } else if (strcmp(arg[iarg],"xy") == 0) { scalexy = 0; - if (iarg+4 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); p_start[5] = atof(arg[iarg+1]); p_stop[5] = atof(arg[iarg+2]); p_period[5] = atof(arg[iarg+3]); @@ -220,158 +217,158 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) iarg += 4; } else if (strcmp(arg[iarg],"couple") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ; else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY; else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ; else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ; else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"drag") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); drag = atof(arg[iarg+1]); - if (drag < 0.0) error->all("Illegal fix nvt/npt/nph command"); + if (drag < 0.0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"dilate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"all") == 0) allremap = 1; else if (strcmp(arg[iarg+1],"partial") == 0) allremap = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"tchain") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); mtchain = atoi(arg[iarg+1]); // used by FixNVTSllod to preserve non-default value mtchain_default_flag = 0; - if (mtchain < 1) error->all("Illegal fix nvt/npt/nph command"); + if (mtchain < 1) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"pchain") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); mpchain = atoi(arg[iarg+1]); - if (mpchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (mpchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"mtk") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"yes") == 0) mtk_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) mtk_flag = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"tloop") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nc_tchain = atoi(arg[iarg+1]); - if (nc_tchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nc_tchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"ploop") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nc_pchain = atoi(arg[iarg+1]); - if (nc_pchain < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nc_pchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"nreset") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); nreset_h0 = atoi(arg[iarg+1]); - if (nreset_h0 < 0) error->all("Illegal fix nvt/npt/nph command"); + if (nreset_h0 < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"scalexy") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"yes") == 0) scalexy = 1; else if (strcmp(arg[iarg+1],"no") == 0) scalexy = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"scalexz") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"yes") == 0) scalexz = 1; else if (strcmp(arg[iarg+1],"no") == 0) scalexz = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; } else if (strcmp(arg[iarg],"scaleyz") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nvt/npt/nph command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command"); if (strcmp(arg[iarg+1],"yes") == 0) scaleyz = 1; else if (strcmp(arg[iarg+1],"no") == 0) scaleyz = 0; - else error->all("Illegal fix nvt/npt/nph command"); + else error->all(FLERR,"Illegal fix nvt/npt/nph command"); iarg += 2; - } else error->all("Illegal fix nvt/npt/nph command"); + } else error->all(FLERR,"Illegal fix nvt/npt/nph command"); } // error checks if (dimension == 2 && (p_flag[2] || p_flag[3] || p_flag[4])) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); if (dimension == 2 && (pcouple == YZ || pcouple == XZ)) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); if (dimension == 2 && (scalexz == 1 || scaleyz == 1 )) - error->all("Invalid fix nvt/npt/nph command for a 2d simulation"); + error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation"); if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XYZ && dimension == 3 && p_flag[2] == 0) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0)) - error->all("Invalid fix nvt/npt/nph command pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings"); if (p_flag[0] && domain->xperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[1] && domain->yperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[2] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension"); if (p_flag[3] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (p_flag[4] && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (p_flag[5] && domain->yperiodic == 0) - error->all("Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension"); if (scaleyz == 1 && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph " + error->all(FLERR,"Cannot use fix nvt/npt/nph " "with yz dynamics when z is non-periodic dimension"); if (scalexz == 1 && domain->zperiodic == 0) - error->all("Cannot use fix nvt/npt/nph " + error->all(FLERR,"Cannot use fix nvt/npt/nph " "with xz dynamics when z is non-periodic dimension"); if (scalexy == 1 && domain->yperiodic == 0) - error->all("Cannot use fix nvt/npt/nph " + error->all(FLERR,"Cannot use fix nvt/npt/nph " "with xy dynamics when y is non-periodic dimension"); if (p_flag[3] && scaleyz == 1) - error->all("Cannot use fix nvt/npt/nph with" + error->all(FLERR,"Cannot use fix nvt/npt/nph with" "both yz dynamics and yz scaling"); if (p_flag[4] && scalexz == 1) - error->all("Cannot use fix nvt/npt/nph with " + error->all(FLERR,"Cannot use fix nvt/npt/nph with " "both xz dynamics and xz scaling"); if (p_flag[5] && scalexy == 1) - error->all("Cannot use fix nvt/npt/nph with " + error->all(FLERR,"Cannot use fix nvt/npt/nph with " "both xy dynamics and xy scaling"); if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5])) - error->all("Can not specify Pxy/Pxz/Pyz in " + error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in " "fix nvt/npt/nph with non-triclinic box"); if (pcouple == XYZ && dimension == 3 && (p_start[0] != p_start[1] || p_start[0] != p_start[2] || p_stop[0] != p_stop[1] || p_stop[0] != p_stop[2] || p_period[0] != p_period[1] || p_period[0] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XYZ && dimension == 2 && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XY && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == YZ && (p_start[1] != p_start[2] || p_stop[1] != p_stop[2] || p_period[1] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if (pcouple == XZ && (p_start[0] != p_start[2] || p_stop[0] != p_stop[2] || p_period[0] != p_period[2])) - error->all("Invalid fix nvt/npt/nph pressure settings"); + error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings"); if ((tstat_flag && t_period <= 0.0) || (p_flag[0] && p_period[0] <= 0.0) || @@ -380,7 +377,7 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) (p_flag[3] && p_period[3] <= 0.0) || (p_flag[4] && p_period[4] <= 0.0) || (p_flag[5] && p_period[5] <= 0.0)) - error->all("Fix nvt/npt/nph damping parameters must be > 0.0"); + error->all(FLERR,"Fix nvt/npt/nph damping parameters must be > 0.0"); // set pstat_flag and box change and restart_pbc variables @@ -544,7 +541,7 @@ void FixNH::init() if ((p_flag[0] && dimflag[0]) || (p_flag[1] && dimflag[1]) || (p_flag[2] && dimflag[2]) || (p_flag[3] && dimflag[3]) || (p_flag[4] && dimflag[4]) || (p_flag[5] && dimflag[5])) - error->all("Cannot use fix npt and fix deform on " + error->all(FLERR,"Cannot use fix npt and fix deform on " "same component of stress tensor"); } @@ -552,7 +549,7 @@ void FixNH::init() int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix nvt/nph/npt does not exist"); + error->all(FLERR,"Temperature ID for fix nvt/nph/npt does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -560,7 +557,7 @@ void FixNH::init() if (pstat_flag) { icompute = modify->find_compute(id_press); - if (icompute < 0) error->all("Pressure ID for fix npt/nph does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for fix npt/nph does not exist"); pressure = modify->compute[icompute]; } @@ -1092,7 +1089,7 @@ void FixNH::remap() if (domain->yz < -TILTMAX*domain->yprd || domain->yz > TILTMAX*domain->yprd || domain->xz < -TILTMAX*domain->xprd || domain->xz > TILTMAX*domain->xprd || domain->xy < -TILTMAX*domain->xprd || domain->xy > TILTMAX*domain->xprd) - error->all("Fix npt/nph has tilted box too far in one step - " + error->all(FLERR,"Fix npt/nph has tilted box too far in one step - " "periodic cell is too far from equilibrium state"); domain->set_global_box(); @@ -1263,7 +1260,7 @@ void FixNH::restart(char *buf) int FixNH::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -1274,28 +1271,28 @@ int FixNH::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for fix modify is not for group all"); + error->warning(FLERR,"Temperature for fix modify is not for group all"); // reset id_temp of pressure to new temperature ID if (pstat_flag) { icompute = modify->find_compute(id_press); if (icompute < 0) - error->all("Pressure ID for fix modify does not exist"); + error->all(FLERR,"Pressure ID for fix modify does not exist"); modify->compute[icompute]->reset_extra_compute_fix(id_temp); } return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); - if (!pstat_flag) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + if (!pstat_flag) error->all(FLERR,"Illegal fix_modify command"); if (pflag) { modify->delete_compute(id_press); pflag = 0; @@ -1306,11 +1303,11 @@ int FixNH::modify_param(int narg, char **arg) strcpy(id_press,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); return 2; } diff --git a/src/fix_nh_sphere.cpp b/src/fix_nh_sphere.cpp index ed414e511d..7bdbcee266 100644 --- a/src/fix_nh_sphere.cpp +++ b/src/fix_nh_sphere.cpp @@ -32,7 +32,7 @@ FixNHSphere::FixNHSphere(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (!atom->sphere_flag) - error->all("Fix nvt/nph/npt sphere requires atom style sphere"); + error->all(FLERR,"Fix nvt/nph/npt sphere requires atom style sphere"); } /* ---------------------------------------------------------------------- */ @@ -49,7 +49,7 @@ void FixNHSphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (radius[i] == 0.0) - error->one("Fix nvt/sphere requires extended particles"); + error->one(FLERR,"Fix nvt/sphere requires extended particles"); FixNH::init(); } diff --git a/src/fix_nph.cpp b/src/fix_nph.cpp index b863be12ab..e65da36589 100644 --- a/src/fix_nph.cpp +++ b/src/fix_nph.cpp @@ -24,9 +24,9 @@ FixNPH::FixNPH(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (tstat_flag) - error->all("Temperature control can not be used with fix nph"); + error->all(FLERR,"Temperature control can not be used with fix nph"); if (!pstat_flag) - error->all("Pressure control must be used with fix nph"); + error->all(FLERR,"Pressure control must be used with fix nph"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_nph_sphere.cpp b/src/fix_nph_sphere.cpp index bc0e23a3b6..550dd8f5bc 100644 --- a/src/fix_nph_sphere.cpp +++ b/src/fix_nph_sphere.cpp @@ -24,9 +24,9 @@ FixNPHSphere::FixNPHSphere(LAMMPS *lmp, int narg, char **arg) : FixNHSphere(lmp, narg, arg) { if (tstat_flag) - error->all("Temperature control can not be used with fix nph/sphere"); + error->all(FLERR,"Temperature control can not be used with fix nph/sphere"); if (!pstat_flag) - error->all("Pressure control must be used with fix nph/sphere"); + error->all(FLERR,"Pressure control must be used with fix nph/sphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_npt.cpp b/src/fix_npt.cpp index 3963e69ebb..84522560ac 100644 --- a/src/fix_npt.cpp +++ b/src/fix_npt.cpp @@ -24,9 +24,9 @@ FixNPT::FixNPT(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix npt"); + error->all(FLERR,"Temperature control must be used with fix npt"); if (!pstat_flag) - error->all("Pressure control must be used with fix npt"); + error->all(FLERR,"Pressure control must be used with fix npt"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_npt_sphere.cpp b/src/fix_npt_sphere.cpp index 2e250fad8d..b58971f550 100644 --- a/src/fix_npt_sphere.cpp +++ b/src/fix_npt_sphere.cpp @@ -24,9 +24,9 @@ FixNPTSphere::FixNPTSphere(LAMMPS *lmp, int narg, char **arg) : FixNHSphere(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix npt/sphere"); + error->all(FLERR,"Temperature control must be used with fix npt/sphere"); if (!pstat_flag) - error->all("Pressure control must be used with fix npt/sphere"); + error->all(FLERR,"Pressure control must be used with fix npt/sphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_nve.cpp b/src/fix_nve.cpp index bb500561ae..ce4e253069 100644 --- a/src/fix_nve.cpp +++ b/src/fix_nve.cpp @@ -28,7 +28,7 @@ FixNVE::FixNVE(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (strcmp(style,"nve/sphere") != 0 && narg < 3) - error->all("Illegal fix nve command"); + error->all(FLERR,"Illegal fix nve command"); time_integrate = 1; } diff --git a/src/fix_nve_limit.cpp b/src/fix_nve_limit.cpp index 2fed70c49e..a5e2b28946 100644 --- a/src/fix_nve_limit.cpp +++ b/src/fix_nve_limit.cpp @@ -29,7 +29,7 @@ using namespace LAMMPS_NS; FixNVELimit::FixNVELimit(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 4) error->all("Illegal fix nve/limit command"); + if (narg != 4) error->all(FLERR,"Illegal fix nve/limit command"); time_integrate = 1; scalar_flag = 1; diff --git a/src/fix_nve_noforce.cpp b/src/fix_nve_noforce.cpp index b0095ab180..b4d67be752 100644 --- a/src/fix_nve_noforce.cpp +++ b/src/fix_nve_noforce.cpp @@ -26,7 +26,7 @@ using namespace LAMMPS_NS; FixNVENoforce::FixNVENoforce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all("Illegal fix nve/noforce command"); + if (narg != 3) error->all(FLERR,"Illegal fix nve/noforce command"); time_integrate = 1; } diff --git a/src/fix_nve_sphere.cpp b/src/fix_nve_sphere.cpp index 935c9f0699..c81452994c 100644 --- a/src/fix_nve_sphere.cpp +++ b/src/fix_nve_sphere.cpp @@ -33,7 +33,7 @@ enum{NONE,DIPOLE}; FixNVESphere::FixNVESphere(LAMMPS *lmp, int narg, char **arg) : FixNVE(lmp, narg, arg) { - if (narg < 3) error->all("Illegal fix nve/sphere command"); + if (narg < 3) error->all(FLERR,"Illegal fix nve/sphere command"); time_integrate = 1; @@ -44,19 +44,19 @@ FixNVESphere::FixNVESphere(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"update") == 0) { - if (iarg+2 > narg) error->all("Illegal fix nve/sphere command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix nve/sphere command"); if (strcmp(arg[iarg+1],"dipole") == 0) extra = DIPOLE; - else error->all("Illegal fix nve/sphere command"); + else error->all(FLERR,"Illegal fix nve/sphere command"); iarg += 2; - } else error->all("Illegal fix nve/sphere command"); + } else error->all(FLERR,"Illegal fix nve/sphere command"); } // error checks if (!atom->sphere_flag) - error->all("Fix nve/sphere requires atom style sphere"); + error->all(FLERR,"Fix nve/sphere requires atom style sphere"); if (extra == DIPOLE && !atom->mu_flag) - error->all("Fix nve/sphere requires atom attribute mu"); + error->all(FLERR,"Fix nve/sphere requires atom attribute mu"); } /* ---------------------------------------------------------------------- */ @@ -85,7 +85,7 @@ void FixNVESphere::init() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (radius[i] == 0.0) - error->one("Fix nve/sphere requires extended particles"); + error->one(FLERR,"Fix nve/sphere requires extended particles"); FixNVE::init(); } diff --git a/src/fix_nvt.cpp b/src/fix_nvt.cpp index 7817113b05..60478e6c41 100644 --- a/src/fix_nvt.cpp +++ b/src/fix_nvt.cpp @@ -25,9 +25,9 @@ FixNVT::FixNVT(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt"); + error->all(FLERR,"Temperature control must be used with fix nvt"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt"); + error->all(FLERR,"Pressure control can not be used with fix nvt"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_nvt_sllod.cpp b/src/fix_nvt_sllod.cpp index 576d064409..ab5c876ad3 100644 --- a/src/fix_nvt_sllod.cpp +++ b/src/fix_nvt_sllod.cpp @@ -38,9 +38,9 @@ FixNVTSllod::FixNVTSllod(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt/sllod"); + error->all(FLERR,"Temperature control must be used with fix nvt/sllod"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt/sllod"); + error->all(FLERR,"Pressure control can not be used with fix nvt/sllod"); // default values @@ -72,7 +72,7 @@ void FixNVTSllod::init() FixNH::init(); if (!temperature->tempbias) - error->all("Temperature for fix nvt/sllod does not have a bias"); + error->all(FLERR,"Temperature for fix nvt/sllod does not have a bias"); nondeformbias = 0; if (strcmp(temperature->style,"temp/deform") != 0) nondeformbias = 1; @@ -83,12 +83,12 @@ void FixNVTSllod::init() for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"deform") == 0) { if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP) - error->all("Using fix nvt/sllod with inconsistent fix deform " + error->all(FLERR,"Using fix nvt/sllod with inconsistent fix deform " "remap option"); break; } if (i == modify->nfix) - error->all("Using fix nvt/sllod with no fix deform defined"); + error->all(FLERR,"Using fix nvt/sllod with no fix deform defined"); } /* ---------------------------------------------------------------------- diff --git a/src/fix_nvt_sphere.cpp b/src/fix_nvt_sphere.cpp index 9873917c9f..84c4a6bbc6 100644 --- a/src/fix_nvt_sphere.cpp +++ b/src/fix_nvt_sphere.cpp @@ -25,9 +25,9 @@ FixNVTSphere::FixNVTSphere(LAMMPS *lmp, int narg, char **arg) : FixNHSphere(lmp, narg, arg) { if (!tstat_flag) - error->all("Temperature control must be used with fix nvt/sphere"); + error->all(FLERR,"Temperature control must be used with fix nvt/sphere"); if (pstat_flag) - error->all("Pressure control can not be used with fix nvt/sphere"); + error->all(FLERR,"Pressure control can not be used with fix nvt/sphere"); // create a new compute temp style // id = fix-ID + temp diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp index 088c01785f..d0269acddb 100644 --- a/src/fix_orient_fcc.cpp +++ b/src/fix_orient_fcc.cpp @@ -35,9 +35,6 @@ using namespace LAMMPS_NS; #define BIG 1000000000 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : @@ -45,7 +42,7 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : { MPI_Comm_rank(world,&me); - if (narg != 11) error->all("Illegal fix orient/fcc command"); + if (narg != 11) error->all(FLERR,"Illegal fix orient/fcc command"); scalar_flag = 1; global_freq = 1; @@ -76,7 +73,7 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : n = strlen(arg[10]) + 1; chifilename = new char[n]; strcpy(chifilename,arg[10]); - } else error->all("Illegal fix orient/fcc command"); + } else error->all(FLERR,"Illegal fix orient/fcc command"); // initializations @@ -96,22 +93,22 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : int count; FILE *infile = fopen(xifilename,"r"); - if (infile == NULL) error->one("Fix orient/fcc file open failed"); + if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed"); for (int i = 0; i < 6; i++) { result = fgets(line,512,infile); - if (!result) error->one("Fix orient/fcc file read failed"); + if (!result) error->one(FLERR,"Fix orient/fcc file read failed"); count = sscanf(line,"%lg %lg %lg",&Rxi[i][0],&Rxi[i][1],&Rxi[i][2]); - if (count != 3) error->one("Fix orient/fcc file read failed"); + if (count != 3) error->one(FLERR,"Fix orient/fcc file read failed"); } fclose(infile); infile = fopen(chifilename,"r"); - if (infile == NULL) error->one("Fix orient/fcc file open failed"); + if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed"); for (int i = 0; i < 6; i++) { result = fgets(line,512,infile); - if (!result) error->one("Fix orient/fcc file read failed"); + if (!result) error->one(FLERR,"Fix orient/fcc file read failed"); count = sscanf(line,"%lg %lg %lg",&Rchi[i][0],&Rchi[i][1],&Rchi[i][2]); - if (count != 3) error->one("Fix orient/fcc file read failed"); + if (count != 3) error->one(FLERR,"Fix orient/fcc file read failed"); } fclose(infile); } @@ -396,7 +393,7 @@ void FixOrientFCC::post_force(int vflag) for (k = 0; k < nn; k++) { if (id_self == nbr[m].id[k]) { - if (found_myself) error->one("Fix orient/fcc found self twice"); + if (found_myself) error->one(FLERR,"Fix orient/fcc found self twice"); found_myself = true; duxi_other = nbr[m].duxi; dxiptr = &nbr[m].dxi[k][0]; diff --git a/src/fix_planeforce.cpp b/src/fix_planeforce.cpp index 0cf0ee2b92..5b7a0cfbec 100644 --- a/src/fix_planeforce.cpp +++ b/src/fix_planeforce.cpp @@ -27,13 +27,13 @@ using namespace LAMMPS_NS; FixPlaneForce::FixPlaneForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix planeforce command"); + if (narg != 6) error->all(FLERR,"Illegal fix planeforce command"); xdir = atof(arg[3]); ydir = atof(arg[4]); zdir = atof(arg[5]); double len = sqrt(xdir*xdir + ydir*ydir + zdir*zdir); - if (len == 0.0) error->all("Illegal fix planeforce command"); + if (len == 0.0) error->all(FLERR,"Illegal fix planeforce command"); xdir /= len; ydir /= len; diff --git a/src/fix_press_berendsen.cpp b/src/fix_press_berendsen.cpp index 2da7bde7b7..36abc158b2 100644 --- a/src/fix_press_berendsen.cpp +++ b/src/fix_press_berendsen.cpp @@ -29,9 +29,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{NOBIAS,BIAS}; enum{NONE,XYZ,XY,YZ,XZ}; enum{ISO,ANISO}; @@ -41,7 +38,7 @@ enum{ISO,ANISO}; FixPressBerendsen::FixPressBerendsen(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix press/berendsen command"); + if (narg < 5) error->all(FLERR,"Illegal fix press/berendsen command"); box_change = 1; box_change_size = 1; @@ -70,7 +67,7 @@ FixPressBerendsen::FixPressBerendsen(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"iso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); pcouple = XYZ; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -82,7 +79,7 @@ FixPressBerendsen::FixPressBerendsen(LAMMPS *lmp, int narg, char **arg) : } iarg += 4; } else if (strcmp(arg[iarg],"aniso") == 0) { - if (iarg+4 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); pcouple = NONE; p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]); p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]); @@ -95,52 +92,52 @@ FixPressBerendsen::FixPressBerendsen(LAMMPS *lmp, int narg, char **arg) : iarg += 4; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+4 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); p_start[0] = atof(arg[iarg+1]); p_stop[0] = atof(arg[iarg+2]); p_period[0] = atof(arg[iarg+3]); p_flag[0] = 1; iarg += 4; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+4 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); p_start[1] = atof(arg[iarg+1]); p_stop[1] = atof(arg[iarg+2]); p_period[1] = atof(arg[iarg+3]); p_flag[1] = 1; iarg += 4; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+4 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); p_start[2] = atof(arg[iarg+1]); p_stop[2] = atof(arg[iarg+2]); p_period[2] = atof(arg[iarg+3]); p_flag[2] = 1; iarg += 4; if (dimension == 2) - error->all("Invalid fix press/berendsen for a 2d simulation"); + error->all(FLERR,"Invalid fix press/berendsen for a 2d simulation"); } else if (strcmp(arg[iarg],"couple") == 0) { - if (iarg+2 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ; else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY; else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ; else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ; else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE; - else error->all("Illegal fix press/berendsen command"); + else error->all(FLERR,"Illegal fix press/berendsen command"); iarg += 2; } else if (strcmp(arg[iarg],"modulus") == 0) { - if (iarg+2 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); bulkmodulus = atof(arg[iarg+1]); if (bulkmodulus <= 0.0) - error->all("Illegal fix press/berendsen command"); + error->all(FLERR,"Illegal fix press/berendsen command"); iarg += 2; } else if (strcmp(arg[iarg],"dilate") == 0) { - if (iarg+2 > narg) error->all("Illegal fix press/berendsen command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix press/berendsen command"); if (strcmp(arg[iarg+1],"all") == 0) allremap = 1; else if (strcmp(arg[iarg+1],"partial") == 0) allremap = 0; - else error->all("Illegal fix press/berendsen command"); + else error->all(FLERR,"Illegal fix press/berendsen command"); iarg += 2; - } else error->all("Illegal fix press/berendsen command"); + } else error->all(FLERR,"Illegal fix press/berendsen command"); } if (allremap == 0) restart_pbc = 1; @@ -148,54 +145,54 @@ FixPressBerendsen::FixPressBerendsen(LAMMPS *lmp, int narg, char **arg) : // error checks if (dimension == 2 && p_flag[2]) - error->all("Invalid fix press/berendsen for a 2d simulation"); + error->all(FLERR,"Invalid fix press/berendsen for a 2d simulation"); if (dimension == 2 && (pcouple == YZ || pcouple == XZ)) - error->all("Invalid fix press/berendsen for a 2d simulation"); + error->all(FLERR,"Invalid fix press/berendsen for a 2d simulation"); if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XYZ && dimension == 3 && p_flag[2] == 0) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0)) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0)) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0)) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (p_flag[0] && domain->xperiodic == 0) - error->all("Cannot use fix press/berendsen on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix press/berendsen on a non-periodic dimension"); if (p_flag[1] && domain->yperiodic == 0) - error->all("Cannot use fix press/berendsen on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix press/berendsen on a non-periodic dimension"); if (p_flag[2] && domain->zperiodic == 0) - error->all("Cannot use fix press/berendsen on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix press/berendsen on a non-periodic dimension"); if (pcouple == XYZ && dimension == 3 && (p_start[0] != p_start[1] || p_start[0] != p_start[2] || p_stop[0] != p_stop[1] || p_stop[0] != p_stop[2] || p_period[0] != p_period[1] || p_period[0] != p_period[2])) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XYZ && dimension == 2 && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XY && (p_start[0] != p_start[1] || p_stop[0] != p_stop[1] || p_period[0] != p_period[1])) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == YZ && (p_start[1] != p_start[2] || p_stop[1] != p_stop[2] || p_period[1] != p_period[2])) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if (pcouple == XZ && (p_start[0] != p_start[2] || p_stop[0] != p_stop[2] || p_period[0] != p_period[2])) - error->all("Invalid fix press/berendsen pressure settings"); + error->all(FLERR,"Invalid fix press/berendsen pressure settings"); if ((p_flag[0] && p_period[0] <= 0.0) || (p_flag[1] && p_period[1] <= 0.0) || (p_flag[2] && p_period[2] <= 0.0)) - error->all("Fix press/berendsen damping parameters must be > 0.0"); + error->all(FLERR,"Fix press/berendsen damping parameters must be > 0.0"); // pstyle = ISO if XYZ coupling or XY coupling in 2d -> 1 dof // else pstyle = ANISO -> 3 dof @@ -271,7 +268,7 @@ int FixPressBerendsen::setmask() void FixPressBerendsen::init() { if (domain->triclinic) - error->all("Cannot use fix press/berendsen with triclinic box"); + error->all(FLERR,"Cannot use fix press/berendsen with triclinic box"); // insure no conflict with fix deform @@ -280,7 +277,7 @@ void FixPressBerendsen::init() int *dimflag = ((FixDeform *) modify->fix[i])->dimflag; if ((p_flag[0] && dimflag[0]) || (p_flag[1] && dimflag[1]) || (p_flag[2] && dimflag[2])) - error->all("Cannot use fix press/berendsen and " + error->all(FLERR,"Cannot use fix press/berendsen and " "fix deform on same component of stress tensor"); } @@ -288,7 +285,7 @@ void FixPressBerendsen::init() int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix press/berendsen does not exist"); + error->all(FLERR,"Temperature ID for fix press/berendsen does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -296,7 +293,7 @@ void FixPressBerendsen::init() icompute = modify->find_compute(id_press); if (icompute < 0) - error->all("Pressure ID for fix press/berendsen does not exist"); + error->all(FLERR,"Pressure ID for fix press/berendsen does not exist"); pressure = modify->compute[icompute]; // Kspace setting @@ -462,7 +459,7 @@ void FixPressBerendsen::remap() int FixPressBerendsen::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -473,25 +470,25 @@ int FixPressBerendsen::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for NPT is not for group all"); + error->warning(FLERR,"Temperature for NPT is not for group all"); // reset id_temp of pressure to new temperature ID icompute = modify->find_compute(id_press); if (icompute < 0) - error->all("Pressure ID for fix press/berendsen does not exist"); + error->all(FLERR,"Pressure ID for fix press/berendsen does not exist"); modify->compute[icompute]->reset_extra_compute_fix(id_temp); return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (pflag) { modify->delete_compute(id_press); pflag = 0; @@ -502,11 +499,11 @@ int FixPressBerendsen::modify_param(int narg, char **arg) strcpy(id_press,arg[1]); int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all("Could not find fix_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); return 2; } return 0; diff --git a/src/fix_print.cpp b/src/fix_print.cpp index 682c7b1b51..c38945a8c0 100644 --- a/src/fix_print.cpp +++ b/src/fix_print.cpp @@ -29,9 +29,9 @@ using namespace LAMMPS_NS; FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix print command"); + if (narg < 5) error->all(FLERR,"Illegal fix print command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix print command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix print command"); MPI_Comm_rank(world,&me); @@ -48,31 +48,31 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : int iarg = 5; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0 || strcmp(arg[iarg],"append") == 0) { - if (iarg+2 > narg) error->all("Illegal fix print command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); if (me == 0) { if (strcmp(arg[iarg],"file") == 0) fp = fopen(arg[iarg+1],"w"); else fp = fopen(arg[iarg+1],"a"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix print file %s",arg[iarg+1]); - error->one(str); + error->one(FLERR,str); } } iarg += 2; } else if (strcmp(arg[iarg],"screen") == 0) { - if (iarg+2 > narg) error->all("Illegal fix print command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); if (strcmp(arg[iarg+1],"yes") == 0) screenflag = 1; else if (strcmp(arg[iarg+1],"no") == 0) screenflag = 0; - else error->all("Illegal fix print command"); + else error->all(FLERR,"Illegal fix print command"); iarg += 2; } else if (strcmp(arg[iarg],"title") == 0) { - if (iarg+2 > narg) error->all("Illegal fix print command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); delete [] title; int n = strlen(arg[iarg+1]) + 1; title = new char[n]; strcpy(title,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix print command"); + } else error->all(FLERR,"Illegal fix print command"); } // print file comment line diff --git a/src/fix_recenter.cpp b/src/fix_recenter.cpp index cd2b311c9a..ac752b99c3 100644 --- a/src/fix_recenter.cpp +++ b/src/fix_recenter.cpp @@ -35,7 +35,7 @@ enum{BOX,LATTICE,FRACTION}; FixRecenter::FixRecenter(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix recenter command"); + if (narg < 6) error->all(FLERR,"Illegal fix recenter command"); xcom = ycom = zcom = 0.0; xflag = yflag = zflag = 1; @@ -60,22 +60,22 @@ FixRecenter::FixRecenter(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"shift") == 0) { int igroup2 = group->find(arg[iarg+1]); - if (igroup2 < 0) error->all("Could not find fix recenter group ID"); + if (igroup2 < 0) error->all(FLERR,"Could not find fix recenter group ID"); group2bit = group->bitmask[igroup2]; iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { if (strcmp(arg[iarg+1],"box") == 0) scaleflag = BOX; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = LATTICE; else if (strcmp(arg[iarg+1],"fraction") == 0) scaleflag = FRACTION; - else error->all("Illegal fix recenter command"); + else error->all(FLERR,"Illegal fix recenter command"); iarg += 2; - } else error->all("Illegal fix recenter command"); + } else error->all(FLERR,"Illegal fix recenter command"); } // scale xcom,ycom,zcom if (scaleflag == LATTICE && domain->lattice == NULL) - error->all("Use of fix recenter with undefined lattice"); + error->all(FLERR,"Use of fix recenter with undefined lattice"); double xscale,yscale,zscale; if (scaleflag == LATTICE) { @@ -92,7 +92,7 @@ FixRecenter::FixRecenter(LAMMPS *lmp, int narg, char **arg) : // cannot have 0 atoms in group if (group->count(igroup) == 0) - error->all("Fix recenter group has no atoms"); + error->all(FLERR,"Fix recenter group has no atoms"); } /* ---------------------------------------------------------------------- */ @@ -117,7 +117,7 @@ void FixRecenter::init() else if ((modify->fmask[i] & INITIAL_INTEGRATE) && after) flag = 1; } if (flag && comm->me == 0) - error->warning("Fix recenter should come after all other integration fixes"); + error->warning(FLERR,"Fix recenter should come after all other integration fixes"); masstotal = group->mass(igroup); diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp index b9e16c7a41..43f7f61087 100644 --- a/src/fix_restrain.cpp +++ b/src/fix_restrain.cpp @@ -41,7 +41,7 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { int iarg = 6; - if (narg < iarg) error->all("Illegal fix restrain command"); + if (narg < iarg) error->all(FLERR,"Illegal fix restrain command"); scalar_flag = 1; global_freq = 1; @@ -56,11 +56,11 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[5], "dihedral") == 0) { rstyle = DIHEDRAL; n_atoms = 4; - } else error->all("Illegal fix restrain command"); + } else error->all(FLERR,"Illegal fix restrain command"); n_bonds = (narg - iarg) / (n_atoms + 1); if (narg != iarg + n_bonds * (n_atoms + 1)) - error->all("Illegal fix restrain command"); + error->all(FLERR,"Illegal fix restrain command"); // allocate arrays @@ -98,7 +98,7 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : // require atom map to lookup atom IDs if (atom->map_style == 0) - error->all("Fix restrain requires an atom map, see atom_modify"); + error->all(FLERR,"Fix restrain requires an atom map, see atom_modify"); } /* ---------------------------------------------------------------------- */ @@ -218,7 +218,7 @@ void FixRestrain::restrain_dihedral() BIGINT_FORMAT, atom_id[n][0],atom_id[n][1],atom_id[n][2],atom_id[n][3], comm->me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } } else { if ((i1 == -1 || i1 >= nlocal) && (i2 == -1 || i2 >= nlocal) && @@ -230,7 +230,7 @@ void FixRestrain::restrain_dihedral() BIGINT_FORMAT, atom_id[n][0],atom_id[n][1],atom_id[n][2],atom_id[n][3], comm->me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } } @@ -291,7 +291,7 @@ void FixRestrain::restrain_dihedral() sprintf(str,"Restrain problem: %d " BIGINT_FORMAT " %d %d %d %d", me,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - error->warning(str); + error->warning(FLERR,str); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp index b2b79a5af7..cf63dfa116 100644 --- a/src/fix_rigid.cpp +++ b/src/fix_rigid.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; #define TOLERANCE 1.0e-6 #define EPSILON 1.0e-7 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : @@ -71,7 +68,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // parse args for rigid body specification // set nbody and body[i] for each atom - if (narg < 4) error->all("Illegal fix rigid command"); + if (narg < 4) error->all(FLERR,"Illegal fix rigid command"); int iarg; // single rigid body @@ -99,7 +96,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[3],"molecule") == 0) { iarg = 4; if (atom->molecule_flag == 0) - error->all("Fix rigid molecule requires atom attribute molecule"); + error->all(FLERR,"Fix rigid molecule requires atom attribute molecule"); int *mask = atom->mask; int *molecule = atom->molecule; @@ -141,17 +138,17 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // error if atom belongs to more than 1 rigid body } else if (strcmp(arg[3],"group") == 0) { - if (narg < 5) error->all("Illegal fix rigid command"); + if (narg < 5) error->all(FLERR,"Illegal fix rigid command"); nbody = atoi(arg[4]); - if (nbody <= 0) error->all("Illegal fix rigid command"); - if (narg < 5+nbody) error->all("Illegal fix rigid command"); + if (nbody <= 0) error->all(FLERR,"Illegal fix rigid command"); + if (narg < 5+nbody) error->all(FLERR,"Illegal fix rigid command"); iarg = 5+nbody; int *igroups = new int[nbody]; for (ibody = 0; ibody < nbody; ibody++) { igroups[ibody] = group->find(arg[5+ibody]); if (igroups[ibody] == -1) - error->all("Could not find fix rigid group ID"); + error->all(FLERR,"Could not find fix rigid group ID"); } int *mask = atom->mask; @@ -171,15 +168,15 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall) - error->all("One or more atoms belong to multiple rigid bodies"); + error->all(FLERR,"One or more atoms belong to multiple rigid bodies"); delete [] igroups; - } else error->all("Illegal fix rigid command"); + } else error->all(FLERR,"Illegal fix rigid command"); // error check on nbody - if (nbody == 0) error->all("No rigid bodies defined"); + if (nbody == 0) error->all(FLERR,"No rigid bodies defined"); // create all nbody-length arrays @@ -233,7 +230,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"force") == 0) { - if (iarg+5 > narg) error->all("Illegal fix rigid command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command"); int mlo,mhi; force->bounds(arg[iarg+1],nbody,mlo,mhi); @@ -241,16 +238,16 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : double xflag,yflag,zflag; if (strcmp(arg[iarg+2],"off") == 0) xflag = 0.0; else if (strcmp(arg[iarg+2],"on") == 0) xflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (strcmp(arg[iarg+3],"off") == 0) yflag = 0.0; else if (strcmp(arg[iarg+3],"on") == 0) yflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (strcmp(arg[iarg+4],"off") == 0) zflag = 0.0; else if (strcmp(arg[iarg+4],"on") == 0) zflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (domain->dimension == 2 && zflag == 1.0) - error->all("Fix rigid z force cannot be on for 2d simulation"); + error->all(FLERR,"Fix rigid z force cannot be on for 2d simulation"); int count = 0; for (int m = mlo; m <= mhi; m++) { @@ -259,12 +256,12 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : fflag[m-1][2] = zflag; count++; } - if (count == 0) error->all("Illegal fix rigid command"); + if (count == 0) error->all(FLERR,"Illegal fix rigid command"); iarg += 5; } else if (strcmp(arg[iarg],"torque") == 0) { - if (iarg+5 > narg) error->all("Illegal fix rigid command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command"); int mlo,mhi; force->bounds(arg[iarg+1],nbody,mlo,mhi); @@ -272,16 +269,16 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : double xflag,yflag,zflag; if (strcmp(arg[iarg+2],"off") == 0) xflag = 0.0; else if (strcmp(arg[iarg+2],"on") == 0) xflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (strcmp(arg[iarg+3],"off") == 0) yflag = 0.0; else if (strcmp(arg[iarg+3],"on") == 0) yflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (strcmp(arg[iarg+4],"off") == 0) zflag = 0.0; else if (strcmp(arg[iarg+4],"on") == 0) zflag = 1.0; - else error->all("Illegal fix rigid command"); + else error->all(FLERR,"Illegal fix rigid command"); if (domain->dimension == 2 && (xflag == 1.0 || yflag == 1.0)) - error->all("Fix rigid xy torque cannot be on for 2d simulation"); + error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation"); int count = 0; for (int m = mlo; m <= mhi; m++) { @@ -290,28 +287,28 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : tflag[m-1][2] = zflag; count++; } - if (count == 0) error->all("Illegal fix rigid command"); + if (count == 0) error->all(FLERR,"Illegal fix rigid command"); iarg += 5; } else if (strcmp(arg[iarg],"langevin") == 0) { - if (iarg+5 > narg) error->all("Illegal fix rigid command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command"); if (strcmp(style,"rigid") != 0 && strcmp(style,"rigid/nve") != 0) - error->all("Illegal fix rigid command"); + error->all(FLERR,"Illegal fix rigid command"); langflag = 1; t_start = atof(arg[iarg+1]); t_stop = atof(arg[iarg+2]); t_period = atof(arg[iarg+3]); seed = atoi(arg[iarg+4]); if (t_period <= 0.0) - error->all("Fix rigid langevin period must be > 0.0"); - if (seed <= 0) error->all("Illegal fix rigid command"); + error->all(FLERR,"Fix rigid langevin period must be > 0.0"); + if (seed <= 0) error->all(FLERR,"Illegal fix rigid command"); iarg += 5; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+4 > narg) error->all("Illegal fix rigid command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command"); if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0) - error->all("Illegal fix rigid command"); + error->all(FLERR,"Illegal fix rigid command"); tempflag = 1; t_start = atof(arg[iarg+1]); t_stop = atof(arg[iarg+2]); @@ -319,9 +316,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : iarg += 4; } else if (strcmp(arg[iarg],"press") == 0) { - if (iarg+4 > narg) error->all("Illegal fix rigid command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command"); if (strcmp(style,"rigid/npt") != 0) - error->all("Illegal fix rigid command"); + error->all(FLERR,"Illegal fix rigid command"); pressflag = 1; p_start = atof(arg[iarg+1]); p_stop = atof(arg[iarg+2]); @@ -329,22 +326,22 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : iarg += 4; } else if (strcmp(arg[iarg],"tparam") == 0) { - if (iarg+4 > narg) error->all("Illegal fix rigid command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command"); if (strcmp(style,"rigid/nvt") != 0) - error->all("Illegal fix rigid command"); + error->all(FLERR,"Illegal fix rigid command"); t_chain = atoi(arg[iarg+1]); t_iter = atoi(arg[iarg+2]); t_order = atoi(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"pparam") == 0) { - if (iarg+2 > narg) error->all("Illegal fix rigid command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command"); if (strcmp(style,"rigid/npt") != 0) - error->all("Illegal fix rigid command"); + error->all(FLERR,"Illegal fix rigid command"); p_chain = atoi(arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix rigid command"); + } else error->all(FLERR,"Illegal fix rigid command"); } // initialize Marsaglia RNG with processor-unique seed @@ -376,7 +373,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : delete [] ncount; for (ibody = 0; ibody < nbody; ibody++) - if (nrigid[ibody] <= 1) error->all("One or zero atoms in rigid body"); + if (nrigid[ibody] <= 1) error->all(FLERR,"One or zero atoms in rigid body"); // set image flags for each rigid body to default values // will be reset during init() based on xcm and then by pre_neighbor() @@ -481,7 +478,7 @@ void FixRigid::init() int count = 0; for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"rigid") == 0) count++; - if (count > 1 && me == 0) error->warning("More than one fix rigid"); + if (count > 1 && me == 0) error->warning(FLERR,"More than one fix rigid"); // error if npt,nph fix comes before rigid fix @@ -492,7 +489,7 @@ void FixRigid::init() if (i < modify->nfix) { for (int j = i; j < modify->nfix; j++) if (strcmp(modify->fix[j]->style,"rigid") == 0) - error->all("Rigid fix must come before NPT/NPH fix"); + error->all(FLERR,"Rigid fix must come before NPT/NPH fix"); } // timestep info @@ -595,7 +592,7 @@ void FixRigid::init() if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) || (zbox && !periodicity[2])) - error->one("Fix rigid atom has non-zero image flag " + error->one(FLERR,"Fix rigid atom has non-zero image flag " "in a non-periodic dimension"); if (triclinic == 0) { @@ -718,7 +715,7 @@ void FixRigid::init() tensor[0][1] = tensor[1][0] = all[ibody][5]; ierror = MathExtra::jacobi(tensor,inertia[ibody],evectors); - if (ierror) error->all("Insufficient Jacobi rotations for rigid body"); + if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for rigid body"); ex_space[ibody][0] = evectors[0][0]; ex_space[ibody][1] = evectors[1][0]; @@ -864,30 +861,30 @@ void FixRigid::init() for (ibody = 0; ibody < nbody; ibody++) { if (inertia[ibody][0] == 0.0) { if (fabs(all[ibody][0]) > TOLERANCE) - error->all("Fix rigid: Bad principal moments"); + error->all(FLERR,"Fix rigid: Bad principal moments"); } else { if (fabs((all[ibody][0]-inertia[ibody][0])/inertia[ibody][0]) > - TOLERANCE) error->all("Fix rigid: Bad principal moments"); + TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments"); } if (inertia[ibody][1] == 0.0) { if (fabs(all[ibody][1]) > TOLERANCE) - error->all("Fix rigid: Bad principal moments"); + error->all(FLERR,"Fix rigid: Bad principal moments"); } else { if (fabs((all[ibody][1]-inertia[ibody][1])/inertia[ibody][1]) > - TOLERANCE) error->all("Fix rigid: Bad principal moments"); + TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments"); } if (inertia[ibody][2] == 0.0) { if (fabs(all[ibody][2]) > TOLERANCE) - error->all("Fix rigid: Bad principal moments"); + error->all(FLERR,"Fix rigid: Bad principal moments"); } else { if (fabs((all[ibody][2]-inertia[ibody][2])/inertia[ibody][2]) > - TOLERANCE) error->all("Fix rigid: Bad principal moments"); + TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments"); } norm = (inertia[ibody][0] + inertia[ibody][1] + inertia[ibody][2]) / 3.0; if (fabs(all[ibody][3]/norm) > TOLERANCE || fabs(all[ibody][4]/norm) > TOLERANCE || fabs(all[ibody][5]/norm) > TOLERANCE) - error->all("Fix rigid: Bad principal moments"); + error->all(FLERR,"Fix rigid: Bad principal moments"); } // temperature scale factor @@ -1459,7 +1456,7 @@ int FixRigid::dof(int igroup) nall[ibody]+mall[ibody] != nrigid[ibody]) flag = 1; } if (flag && me == 0) - error->warning("Computing temperature of portions of rigid bodies"); + error->warning(FLERR,"Computing temperature of portions of rigid bodies"); // remove appropriate DOFs for each rigid body wholly in temperature group // N = # of point particles in body diff --git a/src/fix_rigid_nvt.cpp b/src/fix_rigid_nvt.cpp index bad5e961df..824f8b4bbf 100644 --- a/src/fix_rigid_nvt.cpp +++ b/src/fix_rigid_nvt.cpp @@ -51,16 +51,16 @@ FixRigidNVT::FixRigidNVT(LAMMPS *lmp, int narg, char **arg) : // convert input period to frequency if (tempflag == 0) - error->all("Did not set temp for fix rigid/nvt"); + error->all(FLERR,"Did not set temp for fix rigid/nvt"); if (t_start < 0.0 || t_stop <= 0.0) - error->all("Target temperature for fix rigid/nvt cannot be 0.0"); - if (t_period <= 0.0) error->all("Fix rigid/nvt period must be > 0.0"); + error->all(FLERR,"Target temperature for fix rigid/nvt cannot be 0.0"); + if (t_period <= 0.0) error->all(FLERR,"Fix rigid/nvt period must be > 0.0"); t_freq = 1.0 / t_period; - if (t_chain < 1) error->all("Illegal fix_modify command"); - if (t_iter < 1) error->all("Illegal fix_modify command"); + if (t_chain < 1) error->all(FLERR,"Illegal fix_modify command"); + if (t_iter < 1) error->all(FLERR,"Illegal fix_modify command"); if (t_order != 3 && t_order != 5) - error->all("Fix_modify order must be 3 or 5"); + error->all(FLERR,"Fix_modify order must be 3 or 5"); allocate_chain(); allocate_order(); @@ -647,7 +647,7 @@ void FixRigidNVT::restart(char *buf) int t_chain_prev = static_cast (list[n++]); if (t_chain_prev != t_chain) - error->all("Cannot restart fix rigid/nvt with different # of chains"); + error->all(FLERR,"Cannot restart fix rigid/nvt with different # of chains"); for (int i = 0; i < t_chain; i++) { eta_t[i] = list[n++]; diff --git a/src/fix_setforce.cpp b/src/fix_setforce.cpp index 897aad56a9..c7dba74f59 100644 --- a/src/fix_setforce.cpp +++ b/src/fix_setforce.cpp @@ -34,7 +34,7 @@ enum{NONE,CONSTANT,EQUAL,ATOM}; FixSetForce::FixSetForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix setforce command"); + if (narg < 6) error->all(FLERR,"Illegal fix setforce command"); vector_flag = 1; size_vector = 3; @@ -82,15 +82,15 @@ FixSetForce::FixSetForce(LAMMPS *lmp, int narg, char **arg) : int iarg = 6; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { - if (iarg+2 > narg) error->all("Illegal fix setforce command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix setforce command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) - error->all("Region ID for fix setforce does not exist"); + error->all(FLERR,"Region ID for fix setforce does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; - } else error->all("Illegal fix setforce command"); + } else error->all(FLERR,"Illegal fix setforce command"); } force_flag = 0; @@ -130,31 +130,31 @@ void FixSetForce::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for fix setforce does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for fix setforce does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; - else error->all("Variable for fix setforce is invalid style"); + else error->all(FLERR,"Variable for fix setforce is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for fix setforce does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for fix setforce does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; - else error->all("Variable for fix setforce is invalid style"); + else error->all(FLERR,"Variable for fix setforce is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for fix setforce does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for fix setforce does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; - else error->all("Variable for fix setforce is invalid style"); + else error->all(FLERR,"Variable for fix setforce is invalid style"); } // set index and check validity of region if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all("Region ID for fix setforce does not exist"); + if (iregion == -1) error->all(FLERR,"Region ID for fix setforce does not exist"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) @@ -179,7 +179,7 @@ void FixSetForce::init() if (zstyle == CONSTANT && zvalue != 0.0) flag = 1; } if (flag) - error->all("Cannot use non-zero forces in an energy minimization"); + error->all(FLERR,"Cannot use non-zero forces in an energy minimization"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp index fca15216f3..e00e84e424 100644 --- a/src/fix_shake.cpp +++ b/src/fix_shake.cpp @@ -37,8 +37,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 #define MASSDELTA 0.1 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) /* ---------------------------------------------------------------------- */ @@ -56,7 +54,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : // error check if (atom->molecular == 0) - error->all("Cannot use fix shake with non-molecular system"); + error->all(FLERR,"Cannot use fix shake with non-molecular system"); // perform initial allocation of atom-based arrays // register with Atom class @@ -74,7 +72,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : // parse SHAKE args - if (narg < 8) error->all("Illegal fix shake command"); + if (narg < 8) error->all(FLERR,"Illegal fix shake command"); tolerance = atof(arg[3]); max_iter = atoi(arg[4]); @@ -109,28 +107,28 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : } else if (mode == 'b') { int i = atoi(arg[next]); if (i < 1 || i > atom->nbondtypes) - error->all("Invalid bond type index for fix shake"); + error->all(FLERR,"Invalid bond type index for fix shake"); bond_flag[i] = 1; } else if (mode == 'a') { int i = atoi(arg[next]); if (i < 1 || i > atom->nangletypes) - error->all("Invalid angle type index for fix shake"); + error->all(FLERR,"Invalid angle type index for fix shake"); angle_flag[i] = 1; } else if (mode == 't') { int i = atoi(arg[next]); if (i < 1 || i > atom->ntypes) - error->all("Invalid atom type index for fix shake"); + error->all(FLERR,"Invalid atom type index for fix shake"); type_flag[i] = 1; } else if (mode == 'm') { double massone = atof(arg[next]); - if (massone == 0.0) error->all("Invalid atom mass for fix shake"); - if (nmass == atom->ntypes) error->all("Too many masses for fix shake"); + if (massone == 0.0) error->all(FLERR,"Invalid atom mass for fix shake"); + if (nmass == atom->ntypes) error->all(FLERR,"Too many masses for fix shake"); mass_list[nmass++] = massone; - } else error->all("Illegal fix shake command"); + } else error->all(FLERR,"Illegal fix shake command"); next++; } @@ -280,13 +278,13 @@ void FixShake::init() int count = 0; for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"shake") == 0) count++; - if (count > 1) error->all("More than one fix shake"); + if (count > 1) error->all(FLERR,"More than one fix shake"); // cannot use with minimization since SHAKE turns off bonds // that should contribute to potential energy if (update->whichflag == 2) - error->all("Fix shake cannot be used with minimization"); + error->all(FLERR,"Fix shake cannot be used with minimization"); // error if npt,nph fix comes before shake fix @@ -297,7 +295,7 @@ void FixShake::init() if (i < modify->nfix) { for (int j = i; j < modify->nfix; j++) if (strcmp(modify->fix[j]->style,"shake") == 0) - error->all("Shake fix must come before NPT/NPH fix"); + error->all(FLERR,"Shake fix must come before NPT/NPH fix"); } // if rRESPA, find associated fix that must exist @@ -315,7 +313,7 @@ void FixShake::init() // set equilibrium bond distances if (force->bond == NULL) - error->all("Bond potential must be defined for SHAKE"); + error->all(FLERR,"Bond potential must be defined for SHAKE"); for (i = 1; i <= atom->nbondtypes; i++) bond_distance[i] = force->bond->equilibrium_distance(i); @@ -326,7 +324,7 @@ void FixShake::init() for (i = 1; i <= atom->nangletypes; i++) { if (angle_flag[i] == 0) continue; if (force->angle == NULL) - error->all("Angle potential must be defined for SHAKE"); + error->all(FLERR,"Angle potential must be defined for SHAKE"); // scan all atoms for a SHAKE angle cluster // extract bond types for the 2 bonds in the cluster @@ -353,7 +351,7 @@ void FixShake::init() // error check for any bond types that are not the same MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world); - if (flag_all) error->all("Shake angles have different bond types"); + if (flag_all) error->all(FLERR,"Shake angles have different bond types"); // insure all procs have bond types @@ -458,7 +456,7 @@ void FixShake::pre_neighbor() sprintf(str, "Shake atoms %d %d missing on proc %d at step " BIGINT_FORMAT, shake_atom[i][0],shake_atom[i][1],me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2) list[nlist++] = i; } else if (shake_flag[i] % 2 == 1) { @@ -472,7 +470,7 @@ void FixShake::pre_neighbor() BIGINT_FORMAT, shake_atom[i][0],shake_atom[i][1],shake_atom[i][2], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2 && i <= atom3) list[nlist++] = i; } else { @@ -488,7 +486,7 @@ void FixShake::pre_neighbor() shake_atom[i][0],shake_atom[i][1], shake_atom[i][2],shake_atom[i][3], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4) list[nlist++] = i; @@ -813,7 +811,7 @@ void FixShake::find_clusters() } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Did not find fix shake partner info"); + if (flag_all) error->all(FLERR,"Did not find fix shake partner info"); // ----------------------------------------------------- // identify SHAKEable bonds @@ -947,7 +945,7 @@ void FixShake::find_clusters() flag = 0; for (i = 0; i < nlocal; i++) if (nshake[i] > 3) flag = 1; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Shake cluster of more than 4 atoms"); + if (flag_all) error->all(FLERR,"Shake cluster of more than 4 atoms"); flag = 0; for (i = 0; i < nlocal; i++) { @@ -956,7 +954,7 @@ void FixShake::find_clusters() if (partner_shake[i][j] && partner_nshake[i][j] > 1) flag = 1; } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Shake clusters are connected"); + if (flag_all) error->all(FLERR,"Shake clusters are connected"); // ----------------------------------------------------- // set SHAKE arrays that are stored with atoms & add angle constraints @@ -1349,7 +1347,7 @@ void FixShake::shake2(int m) double determ = b*b - 4.0*a*c; if (determ < 0.0) { - error->warning("Shake determinant < 0.0",0); + error->warning(FLERR,"Shake determinant < 0.0",0); determ = 0.0; } @@ -1469,7 +1467,7 @@ void FixShake::shake3(int m) // inverse of matrix double determ = a11*a22 - a12*a21; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = a22*determinv; @@ -1663,7 +1661,7 @@ void FixShake::shake4(int m) double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = determinv * (a22*a33 - a23*a32); @@ -1903,7 +1901,7 @@ void FixShake::shake3angle(int m) double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31; - if (determ == 0.0) error->one("Shake determinant = 0.0"); + if (determ == 0.0) error->one(FLERR,"Shake determinant = 0.0"); double determinv = 1.0/determ; double a11inv = determinv * (a22*a33 - a23*a32); diff --git a/src/fix_shear_history.cpp b/src/fix_shear_history.cpp index 0740a2f257..4e284c7f65 100644 --- a/src/fix_shear_history.cpp +++ b/src/fix_shear_history.cpp @@ -86,7 +86,7 @@ int FixShearHistory::setmask() void FixShearHistory::init() { if (atom->tag_enable == 0) - error->all("Pair style granular with history requires atoms have IDs"); + error->all(FLERR,"Pair style granular with history requires atoms have IDs"); } /* ---------------------------------------------------------------------- */ @@ -166,7 +166,7 @@ void FixShearHistory::pre_exchange() if (npartner[i] >= MAXTOUCH) flag = 1; int flag_all; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Too many touching neighbors - boost MAXTOUCH"); + if (flag_all) error->all(FLERR,"Too many touching neighbors - boost MAXTOUCH"); } /* ---------------------------------------------------------------------- diff --git a/src/fix_spring.cpp b/src/fix_spring.cpp index d6666f2b47..f3ac3e378b 100644 --- a/src/fix_spring.cpp +++ b/src/fix_spring.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; #define SMALL 1.0e-10 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - enum{TETHER,COUPLE}; /* ---------------------------------------------------------------------- */ @@ -40,7 +37,7 @@ enum{TETHER,COUPLE}; FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 9) error->all("Illegal fix spring command"); + if (narg < 9) error->all(FLERR,"Illegal fix spring command"); scalar_flag = 1; vector_flag = 1; @@ -52,7 +49,7 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : group2 = NULL; if (strcmp(arg[3],"tether") == 0) { - if (narg != 9) error->all("Illegal fix spring command"); + if (narg != 9) error->all(FLERR,"Illegal fix spring command"); styleflag = TETHER; k_spring = atof(arg[4]); xflag = yflag = zflag = 1; @@ -63,10 +60,10 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[7],"NULL") == 0) zflag = 0; else zc = atof(arg[7]); r0 = atof(arg[8]); - if (r0 < 0) error->all("R0 < 0 for fix spring command"); + if (r0 < 0) error->all(FLERR,"R0 < 0 for fix spring command"); } else if (strcmp(arg[3],"couple") == 0) { - if (narg != 10) error->all("Illegal fix spring command"); + if (narg != 10) error->all(FLERR,"Illegal fix spring command"); styleflag = COUPLE; int n = strlen(arg[4]) + 1; @@ -74,9 +71,9 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : strcpy(group2,arg[4]); igroup2 = group->find(arg[4]); if (igroup2 == -1) - error->all("Fix spring couple group ID does not exist"); + error->all(FLERR,"Fix spring couple group ID does not exist"); if (igroup2 == igroup) - error->all("Two groups cannot be the same in fix spring couple"); + error->all(FLERR,"Two groups cannot be the same in fix spring couple"); group2bit = group->bitmask[igroup2]; k_spring = atof(arg[5]); @@ -88,9 +85,9 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[8],"NULL") == 0) zflag = 0; else zc = atof(arg[8]); r0 = atof(arg[9]); - if (r0 < 0) error->all("R0 < 0 for fix spring command"); + if (r0 < 0) error->all(FLERR,"R0 < 0 for fix spring command"); - } else error->all("Illegal fix spring command"); + } else error->all(FLERR,"Illegal fix spring command"); ftotal[0] = ftotal[1] = ftotal[2] = ftotal[3] = 0.0; } @@ -123,7 +120,7 @@ void FixSpring::init() if (group2) { igroup2 = group->find(group2); if (igroup2 == -1) - error->all("Fix spring couple group ID does not exist"); + error->all(FLERR,"Fix spring couple group ID does not exist"); group2bit = group->bitmask[igroup2]; } diff --git a/src/fix_spring_rg.cpp b/src/fix_spring_rg.cpp index e4d55eba2d..4723c8fdb9 100644 --- a/src/fix_spring_rg.cpp +++ b/src/fix_spring_rg.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; FixSpringRG::FixSpringRG(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 5) error->all("Illegal fix spring/rg command"); + if (narg != 5) error->all(FLERR,"Illegal fix spring/rg command"); k = atof(arg[3]); rg0_flag = 0; diff --git a/src/fix_spring_self.cpp b/src/fix_spring_self.cpp index 849d7c4787..6fb3472fb6 100644 --- a/src/fix_spring_self.cpp +++ b/src/fix_spring_self.cpp @@ -32,7 +32,7 @@ using namespace LAMMPS_NS; FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 4) error->all("Illegal fix spring/self command"); + if (narg != 4) error->all(FLERR,"Illegal fix spring/self command"); restart_peratom = 1; scalar_flag = 1; @@ -40,7 +40,7 @@ FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) : extscalar = 1; k = atof(arg[3]); - if (k <= 0.0) error->all("Illegal fix spring/self command"); + if (k <= 0.0) error->all(FLERR,"Illegal fix spring/self command"); // perform initial allocation of atom-based array // register with Atom class diff --git a/src/fix_store_force.cpp b/src/fix_store_force.cpp index 5d1e52b64d..98c5f918f8 100644 --- a/src/fix_store_force.cpp +++ b/src/fix_store_force.cpp @@ -27,7 +27,7 @@ using namespace LAMMPS_NS; FixStoreForce::FixStoreForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 3) error->all("Illegal fix store/coord command"); + if (narg < 3) error->all(FLERR,"Illegal fix store/coord command"); peratom_flag = 1; size_peratom_cols = 3; diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index 7f49140d57..8a90365e0f 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -37,13 +37,13 @@ enum{KEYWORD,COMPUTE,FIX,VARIABLE}; FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all("Illegal fix store/state command"); + if (narg < 5) error->all(FLERR,"Illegal fix store/state command"); restart_peratom = 1; peratom_freq = 1; nevery = atoi(arg[3]); - if (nevery < 0) error->all("Illegal fix store/state command"); + if (nevery < 0) error->all(FLERR,"Illegal fix store/state command"); // parse values until one isn't recognized // customize a new keyword by adding to if statement @@ -65,7 +65,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : pack_choice[nvalues++] = &FixStoreState::pack_id; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_molecule; } else if (strcmp(arg[iarg],"type") == 0) { pack_choice[nvalues++] = &FixStoreState::pack_type; @@ -124,60 +124,60 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_muz; } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_radius; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomz; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all("Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqz; } else if (strncmp(arg[iarg],"c_",2) == 0 || @@ -195,7 +195,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') - error->all("Illegal fix store/state command"); + error->all(FLERR,"Illegal fix store/state command"); argindex[nvalues] = atoi(ptr+1); *ptr = '\0'; } else argindex[nvalues] = 0; @@ -217,12 +217,12 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"com") == 0) { - if (iarg+2 > narg) error->all("Illegal fix store/state command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix store/state command"); if (strcmp(arg[iarg+1],"no") == 0) comflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) comflag = 1; - else error->all("Illegal fix store/state command"); + else error->all(FLERR,"Illegal fix store/state command"); iarg += 2; - } else error->all("Illegal fix store/state command"); + } else error->all(FLERR,"Illegal fix store/state command"); } // error check @@ -231,42 +231,42 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all("Compute ID for fix store/state does not exist"); + error->all(FLERR,"Compute ID for fix store/state does not exist"); if (modify->compute[icompute]->peratom_flag == 0) - error->all("Fix store/state compute " + error->all(FLERR,"Fix store/state compute " "does not calculate per-atom values"); if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all("Fix store/state compute does not " + error->all(FLERR,"Fix store/state compute does not " "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all("Fix store/state compute does not " + error->all(FLERR,"Fix store/state compute does not " "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all("Fix store/state compute array is accessed out-of-range"); + error->all(FLERR,"Fix store/state compute array is accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all("Fix ID for fix store/state does not exist"); + error->all(FLERR,"Fix ID for fix store/state does not exist"); if (modify->fix[ifix]->peratom_flag == 0) - error->all("Fix store/state fix does not calculate per-atom values"); + error->all(FLERR,"Fix store/state fix does not calculate per-atom values"); if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all("Fix store/state fix does not calculate a per-atom vector"); + error->all(FLERR,"Fix store/state fix does not calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all("Fix store/state fix does not calculate a per-atom array"); + error->all(FLERR,"Fix store/state fix does not calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all("Fix store/state fix array is accessed out-of-range"); + error->all(FLERR,"Fix store/state fix array is accessed out-of-range"); if (nevery % modify->fix[ifix]->peratom_freq) - error->all("Fix for fix store/state not computed at compatible time"); + error->all(FLERR,"Fix for fix store/state not computed at compatible time"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all("Variable name for fix store/state does not exist"); + error->all(FLERR,"Variable name for fix store/state does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all("Fix store/state variable is not atom-style variable"); + error->all(FLERR,"Fix store/state variable is not atom-style variable"); } } @@ -338,19 +338,19 @@ void FixStoreState::init() if (which[m] == COMPUTE) { int icompute = modify->find_compute(ids[m]); if (icompute < 0) - error->all("Compute ID for fix store/state does not exist"); + error->all(FLERR,"Compute ID for fix store/state does not exist"); value2index[m] = icompute; } else if (which[m] == FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) - error->all("Fix ID for fix store/state does not exist"); + error->all(FLERR,"Fix ID for fix store/state does not exist"); value2index[m] = ifix; } else if (which[m] == VARIABLE) { int ivariable = input->variable->find(ids[m]); if (ivariable < 0) - error->all("Variable name for fix store/state does not exist"); + error->all(FLERR,"Variable name for fix store/state does not exist"); value2index[m] = ivariable; } } diff --git a/src/fix_temp_berendsen.cpp b/src/fix_temp_berendsen.cpp index a74de7d36d..bed8d8bb68 100644 --- a/src/fix_temp_berendsen.cpp +++ b/src/fix_temp_berendsen.cpp @@ -33,7 +33,7 @@ enum{NOBIAS,BIAS}; FixTempBerendsen::FixTempBerendsen(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 6) error->all("Illegal fix temp/berendsen command"); + if (narg != 6) error->all(FLERR,"Illegal fix temp/berendsen command"); // Berendsen thermostat should be applied every step @@ -48,7 +48,7 @@ FixTempBerendsen::FixTempBerendsen(LAMMPS *lmp, int narg, char **arg) : // error checks - if (t_period <= 0.0) error->all("Fix temp/berendsen period must be > 0.0"); + if (t_period <= 0.0) error->all(FLERR,"Fix temp/berendsen period must be > 0.0"); // create a new compute temp style // id = fix-ID + temp, compute group = fix group @@ -95,7 +95,7 @@ void FixTempBerendsen::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/berendsen does not exist"); + error->all(FLERR,"Temperature ID for fix temp/berendsen does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -108,7 +108,7 @@ void FixTempBerendsen::end_of_step() { double t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/berendsen cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/berendsen cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -153,7 +153,7 @@ void FixTempBerendsen::end_of_step() int FixTempBerendsen::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -164,13 +164,13 @@ int FixTempBerendsen::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/fix_temp_rescale.cpp b/src/fix_temp_rescale.cpp index 1b4c8f3f04..d0d67368bc 100644 --- a/src/fix_temp_rescale.cpp +++ b/src/fix_temp_rescale.cpp @@ -35,10 +35,10 @@ enum{NOBIAS,BIAS}; FixTempRescale::FixTempRescale(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 8) error->all("Illegal fix temp/rescale command"); + if (narg < 8) error->all(FLERR,"Illegal fix temp/rescale command"); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix temp/rescale command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix temp/rescale command"); scalar_flag = 1; global_freq = nevery; @@ -94,7 +94,7 @@ void FixTempRescale::init() { int icompute = modify->find_compute(id_temp); if (icompute < 0) - error->all("Temperature ID for fix temp/rescale does not exist"); + error->all(FLERR,"Temperature ID for fix temp/rescale does not exist"); temperature = modify->compute[icompute]; if (temperature->tempbias) which = BIAS; @@ -107,7 +107,7 @@ void FixTempRescale::end_of_step() { double t_current = temperature->compute_scalar(); if (t_current == 0.0) - error->all("Computed temperature for fix temp/rescale cannot be 0.0"); + error->all(FLERR,"Computed temperature for fix temp/rescale cannot be 0.0"); double delta = update->ntimestep - update->beginstep; delta /= update->endstep - update->beginstep; @@ -157,7 +157,7 @@ void FixTempRescale::end_of_step() int FixTempRescale::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); if (tflag) { modify->delete_compute(id_temp); tflag = 0; @@ -168,13 +168,13 @@ int FixTempRescale::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all("Could not find fix_modify temperature ID"); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); if (temperature->igroup != igroup && comm->me == 0) - error->warning("Group for fix_modify temp != fix group"); + error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; } return 0; diff --git a/src/fix_thermal_conductivity.cpp b/src/fix_thermal_conductivity.cpp index b53c3626a6..b339bbd82c 100644 --- a/src/fix_thermal_conductivity.cpp +++ b/src/fix_thermal_conductivity.cpp @@ -31,21 +31,18 @@ using namespace LAMMPS_NS; #define BIG 1.0e10 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixThermalConductivity::FixThermalConductivity(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix thermal/conductivity command"); + if (narg < 6) error->all(FLERR,"Illegal fix thermal/conductivity command"); MPI_Comm_rank(world,&me); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix thermal/conductivity command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix thermal/conductivity command"); scalar_flag = 1; global_freq = nevery; @@ -54,11 +51,11 @@ FixThermalConductivity::FixThermalConductivity(LAMMPS *lmp, if (strcmp(arg[4],"x") == 0) edim = 0; else if (strcmp(arg[4],"y") == 0) edim = 1; else if (strcmp(arg[4],"z") == 0) edim = 2; - else error->all("Illegal fix thermal/conductivity command"); + else error->all(FLERR,"Illegal fix thermal/conductivity command"); nbin = atoi(arg[5]); if (nbin % 2 || nbin <= 2) - error->all("Illegal fix thermal/conductivity command"); + error->all(FLERR,"Illegal fix thermal/conductivity command"); // optional keywords @@ -68,12 +65,12 @@ FixThermalConductivity::FixThermalConductivity(LAMMPS *lmp, while (iarg < narg) { if (strcmp(arg[iarg],"swap") == 0) { if (iarg+2 > narg) - error->all("Illegal fix thermal/conductivity command"); + error->all(FLERR,"Illegal fix thermal/conductivity command"); nswap = atoi(arg[iarg+1]); if (nswap <= 0) - error->all("Fix thermal/conductivity swap value must be positive"); + error->all(FLERR,"Fix thermal/conductivity swap value must be positive"); iarg += 2; - } else error->all("Illegal fix thermal/conductivity command"); + } else error->all(FLERR,"Illegal fix thermal/conductivity command"); } // initialize array sizes to nswap+1 so have space to shift values down @@ -116,7 +113,7 @@ void FixThermalConductivity::init() for (int i = 0; i < modify->nfix; i++) { if (modify->fix[i] == this) foundme = 1; if (foundme && strcmp(modify->fix[i]->style,"ave/spatial") == 0 && me == 0) - error->warning("Fix thermal/conductivity comes before fix ave/spatial"); + error->warning(FLERR,"Fix thermal/conductivity comes before fix ave/spatial"); } // set bounds of 2 slabs in edim diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp index 50865b200a..b73b04c5be 100644 --- a/src/fix_tmd.cpp +++ b/src/fix_tmd.cpp @@ -42,12 +42,12 @@ using namespace LAMMPS_NS; FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 6) error->all("Illegal fix tmd command"); + if (narg < 6) error->all(FLERR,"Illegal fix tmd command"); rho_stop = atof(arg[3]); nfileevery = atoi(arg[5]); - if (rho_stop < 0 || nfileevery < 0) error->all("Illegal fix tmd command"); - if (nfileevery && narg != 7) error->all("Illegal fix tmd command"); + if (rho_stop < 0 || nfileevery < 0) error->all(FLERR,"Illegal fix tmd command"); + if (nfileevery && narg != 7) error->all(FLERR,"Illegal fix tmd command"); MPI_Comm_rank(world,&me); @@ -62,7 +62,7 @@ FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) : // make sure an atom map exists before reading in target coordinates if (atom->map_style == 0) - error->all("Cannot use fix TMD unless atom map exists"); + error->all(FLERR,"Cannot use fix TMD unless atom map exists"); // read from arg[4] and store coordinates of final target in xf @@ -71,13 +71,13 @@ FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) : // open arg[6] statistics file and write header if (nfileevery) { - if (narg != 7) error->all("Illegal fix tmd command"); + if (narg != 7) error->all(FLERR,"Illegal fix tmd command"); if (me == 0) { fp = fopen(arg[6],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix tmd file %s",arg[6]); - error->one(str); + error->one(FLERR,str); } fprintf(fp,"%s %s\n","# Step rho_target rho_old gamma_back", "gamma_forward lambda work_lambda work_analytical"); @@ -169,7 +169,7 @@ void FixTMD::init() if (flag && strcmp(modify->fix[i]->style,"npt") == 0) flag = 2; if (flag && strcmp(modify->fix[i]->style,"nph") == 0) flag = 2; } - if (flag == 2) error->all("Fix tmd must come after integration fixes"); + if (flag == 2) error->all(FLERR,"Fix tmd must come after integration fixes"); // timesteps @@ -465,15 +465,15 @@ void FixTMD::readfile(char *file) continue; } else if (atom->count_words(bufptr) == 4) { if (xprd >= 0.0 || yprd >= 0.0 || zprd >= 0.0) - error->all("Incorrect format in TMD target file"); + error->all(FLERR,"Incorrect format in TMD target file"); imageflag = 0; firstline = 0; } else if (atom->count_words(bufptr) == 7) { if (xprd < 0.0 || yprd < 0.0 || zprd < 0.0) - error->all("Incorrect format in TMD target file"); + error->all(FLERR,"Incorrect format in TMD target file"); imageflag = 1; firstline = 0; - } else error->all("Incorrect format in TMD target file"); + } else error->all(FLERR,"Incorrect format in TMD target file"); } if (imageflag) @@ -521,7 +521,7 @@ void FixTMD::readfile(char *file) int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - if (flagall) error->all("TMD target file did not list all group atoms"); + if (flagall) error->all(FLERR,"TMD target file did not list all group atoms"); } /* ---------------------------------------------------------------------- @@ -541,14 +541,14 @@ void FixTMD::open(char *file) sprintf(gunzip,"gunzip -c %s",file); fp = popen(gunzip,"r"); #else - error->one("Cannot open gzipped file"); + error->one(FLERR,"Cannot open gzipped file"); #endif } if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } } diff --git a/src/fix_ttm.cpp b/src/fix_ttm.cpp index ff037a7804..4bc35c5097 100644 --- a/src/fix_ttm.cpp +++ b/src/fix_ttm.cpp @@ -35,9 +35,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define MAXLINE 1024 /* ---------------------------------------------------------------------- */ @@ -45,7 +42,7 @@ using namespace LAMMPS_NS; FixTTM::FixTTM(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 15) error->all("Illegal fix ttm command"); + if (narg < 15) error->all(FLERR,"Illegal fix ttm command"); vector_flag = 1; size_vector = 2; @@ -70,38 +67,38 @@ FixTTM::FixTTM(LAMMPS *lmp, int narg, char **arg) : if (fpr == NULL) { char str[128]; sprintf(str,"Cannot open file %s",arg[13]); - error->one(str); + error->one(FLERR,str); } nfileevery = atoi(arg[14]); if (nfileevery) { - if (narg != 16) error->all("Illegal fix ttm command"); + if (narg != 16) error->all(FLERR,"Illegal fix ttm command"); MPI_Comm_rank(world,&me); if (me == 0) { fp = fopen(arg[15],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix ttm file %s",arg[15]); - error->one(str); + error->one(FLERR,str); } } } // error check - if (seed <= 0) error->all("Invalid random number seed in fix ttm command"); + if (seed <= 0) error->all(FLERR,"Invalid random number seed in fix ttm command"); if (electronic_specific_heat <= 0.0) - error->all("Fix ttm electronic_specific_heat must be > 0.0"); + error->all(FLERR,"Fix ttm electronic_specific_heat must be > 0.0"); if (electronic_density <= 0.0) - error->all("Fix ttm electronic_density must be > 0.0"); + error->all(FLERR,"Fix ttm electronic_density must be > 0.0"); if (electronic_thermal_conductivity < 0.0) - error->all("Fix ttm electronic_thermal_conductivity must be >= 0.0"); - if (gamma_p <= 0.0) error->all("Fix ttm gamma_p must be > 0.0"); - if (gamma_s < 0.0) error->all("Fix ttm gamma_s must be >= 0.0"); - if (v_0 < 0.0) error->all("Fix ttm v_0 must be >= 0.0"); + error->all(FLERR,"Fix ttm electronic_thermal_conductivity must be >= 0.0"); + if (gamma_p <= 0.0) error->all(FLERR,"Fix ttm gamma_p must be > 0.0"); + if (gamma_s < 0.0) error->all(FLERR,"Fix ttm gamma_s must be >= 0.0"); + if (v_0 < 0.0) error->all(FLERR,"Fix ttm v_0 must be >= 0.0"); if (nxnodes <= 0 || nynodes <= 0 || nznodes <= 0) - error->all("Fix ttm number of nodes must be > 0"); + error->all(FLERR,"Fix ttm number of nodes must be > 0"); v_0_sq = v_0*v_0; @@ -194,11 +191,11 @@ int FixTTM::setmask() void FixTTM::init() { if (domain->dimension == 2) - error->all("Cannot use fix ttm with 2d simulation"); + error->all(FLERR,"Cannot use fix ttm with 2d simulation"); if (domain->nonperiodic != 0) - error->all("Cannot use nonperiodic boundares with fix ttm"); + error->all(FLERR,"Cannot use nonperiodic boundares with fix ttm"); if (domain->triclinic) - error->all("Cannot use fix ttm with triclinic box"); + error->all(FLERR,"Cannot use fix ttm with triclinic box"); // set force prefactors @@ -262,7 +259,7 @@ void FixTTM::post_force(int vflag) while (iznode < 0) iznode += nznodes; if (T_electron[ixnode][iynode][iznode] < 0) - error->all("Electronic temperature dropped below zero"); + error->all(FLERR,"Electronic temperature dropped below zero"); double tsqrt = sqrt(T_electron[ixnode][iynode][iznode]); @@ -345,7 +342,7 @@ void FixTTM::read_initial_electron_temperatures() while (1) { if (fgets(line,MAXLINE,fpr) == NULL) break; sscanf(line,"%d %d %d %lg",&ixnode,&iynode,&iznode,&T_tmp); - if (T_tmp < 0.0) error->one("Fix ttm electron temperatures must be > 0.0"); + if (T_tmp < 0.0) error->one(FLERR,"Fix ttm electron temperatures must be > 0.0"); T_electron[ixnode][iynode][iznode] = T_tmp; T_initial_set[ixnode][iynode][iznode] = 1; } @@ -354,7 +351,7 @@ void FixTTM::read_initial_electron_temperatures() for (int iynode = 0; iynode < nynodes; iynode++) for (int iznode = 0; iznode < nznodes; iznode++) if (T_initial_set[ixnode][iynode][iznode] == 0) - error->one("Initial temperatures not all set in fix ttm"); + error->one(FLERR,"Initial temperatures not all set in fix ttm"); // close file @@ -420,7 +417,7 @@ void FixTTM::end_of_step() num_inner_timesteps = static_cast(update->dt/inner_dt) + 1; inner_dt = update->dt/double(num_inner_timesteps); if (num_inner_timesteps > 1000000) - error->warning("Too many inner timesteps in fix ttm",0); + error->warning(FLERR,"Too many inner timesteps in fix ttm",0); } for (int ith_inner_timestep = 0; ith_inner_timestep < num_inner_timesteps; diff --git a/src/fix_viscosity.cpp b/src/fix_viscosity.cpp index 8191e6d97c..04bcd3394c 100644 --- a/src/fix_viscosity.cpp +++ b/src/fix_viscosity.cpp @@ -32,20 +32,17 @@ using namespace LAMMPS_NS; #define BIG 1.0e10 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ FixViscosity::FixViscosity(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 7) error->all("Illegal fix viscosity command"); + if (narg < 7) error->all(FLERR,"Illegal fix viscosity command"); MPI_Comm_rank(world,&me); nevery = atoi(arg[3]); - if (nevery <= 0) error->all("Illegal fix viscosity command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix viscosity command"); scalar_flag = 1; global_freq = nevery; @@ -54,15 +51,15 @@ FixViscosity::FixViscosity(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[4],"x") == 0) vdim = 0; else if (strcmp(arg[4],"y") == 0) vdim = 1; else if (strcmp(arg[4],"z") == 0) vdim = 2; - else error->all("Illegal fix viscosity command"); + else error->all(FLERR,"Illegal fix viscosity command"); if (strcmp(arg[5],"x") == 0) pdim = 0; else if (strcmp(arg[5],"y") == 0) pdim = 1; else if (strcmp(arg[5],"z") == 0) pdim = 2; - else error->all("Illegal fix viscosity command"); + else error->all(FLERR,"Illegal fix viscosity command"); nbin = atoi(arg[6]); - if (nbin % 2 || nbin <= 2) error->all("Illegal fix viscosity command"); + if (nbin % 2 || nbin <= 2) error->all(FLERR,"Illegal fix viscosity command"); // optional keywords @@ -72,18 +69,18 @@ FixViscosity::FixViscosity(LAMMPS *lmp, int narg, char **arg) : int iarg = 7; while (iarg < narg) { if (strcmp(arg[iarg],"swap") == 0) { - if (iarg+2 > narg) error->all("Illegal fix viscosity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix viscosity command"); nswap = atoi(arg[iarg+1]); - if (nswap <= 0) error->all("Fix viscosity swap value must be positive"); + if (nswap <= 0) error->all(FLERR,"Fix viscosity swap value must be positive"); iarg += 2; } else if (strcmp(arg[iarg],"vtarget") == 0) { - if (iarg+2 > narg) error->all("Illegal fix viscosity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix viscosity command"); if (strcmp(arg[iarg+1],"INF") == 0) vtarget = BIG; else vtarget = atof(arg[iarg+1]); if (vtarget <= 0.0) - error->all("Fix viscosity vtarget value must be positive"); + error->all(FLERR,"Fix viscosity vtarget value must be positive"); iarg += 2; - } else error->all("Illegal fix viscosity command"); + } else error->all(FLERR,"Illegal fix viscosity command"); } // initialize array sizes to nswap+1 so have space to shift values down @@ -126,7 +123,7 @@ void FixViscosity::init() for (int i = 0; i < modify->nfix; i++) { if (modify->fix[i] == this) foundme = 1; if (foundme && strcmp(modify->fix[i]->style,"ave/spatial") == 0 && me == 0) - error->warning("Fix viscosity comes before fix ave/spatial"); + error->warning(FLERR,"Fix viscosity comes before fix ave/spatial"); } // set bounds of 2 slabs in pdim diff --git a/src/fix_viscous.cpp b/src/fix_viscous.cpp index 770eee5593..5345268bb4 100644 --- a/src/fix_viscous.cpp +++ b/src/fix_viscous.cpp @@ -27,7 +27,7 @@ using namespace LAMMPS_NS; FixViscous::FixViscous(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix viscous command"); + if (narg < 4) error->all(FLERR,"Illegal fix viscous command"); double gamma_one = atof(arg[3]); gamma = new double[atom->ntypes+1]; @@ -38,14 +38,14 @@ FixViscous::FixViscous(LAMMPS *lmp, int narg, char **arg) : int iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"scale") == 0) { - if (iarg+3 > narg) error->all("Illegal fix viscous command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal fix viscous command"); int itype = atoi(arg[iarg+1]); double scale = atof(arg[iarg+2]); if (itype <= 0 || itype > atom->ntypes) - error->all("Illegal fix viscous command"); + error->all(FLERR,"Illegal fix viscous command"); gamma[itype] = gamma_one * scale; iarg += 3; - } else error->all("Illegal fix viscous command"); + } else error->all(FLERR,"Illegal fix viscous command"); } } diff --git a/src/fix_wall.cpp b/src/fix_wall.cpp index fdff4a11fb..3cc68017cc 100644 --- a/src/fix_wall.cpp +++ b/src/fix_wall.cpp @@ -51,7 +51,7 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : if ((strcmp(arg[iarg],"xlo") == 0) || (strcmp(arg[iarg],"xhi") == 0) || (strcmp(arg[iarg],"ylo") == 0) || (strcmp(arg[iarg],"yhi") == 0) || (strcmp(arg[iarg],"zlo") == 0) || (strcmp(arg[iarg],"zhi") == 0)) { - if (iarg+5 > narg) error->all("Illegal fix wall command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal fix wall command"); int newwall; if (strcmp(arg[iarg],"xlo") == 0) newwall = XLO; @@ -63,7 +63,7 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : for (int m = 0; m < nwall; m++) if (newwall == wallwhich[m]) - error->all("Wall defined twice in fix wall command"); + error->all(FLERR,"Wall defined twice in fix wall command"); wallwhich[nwall] = newwall; if (strcmp(arg[iarg+1],"EDGE") == 0) { @@ -89,35 +89,35 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : iarg += 5; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal fix wall command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix wall command"); + else error->all(FLERR,"Illegal fix wall command"); iarg += 2; - } else error->all("Illegal fix wall command"); + } else error->all(FLERR,"Illegal fix wall command"); } size_vector = nwall; // error check - if (nwall == 0) error->all("Illegal fix wall command"); + if (nwall == 0) error->all(FLERR,"Illegal fix wall command"); for (int m = 0; m < nwall; m++) if (cutoff[m] <= 0.0) - error->all("Fix wall cutoff <= 0.0"); + error->all(FLERR,"Fix wall cutoff <= 0.0"); for (int m = 0; m < nwall; m++) { if ((wallwhich[m] == XLO || wallwhich[m] == XHI) && domain->xperiodic) - error->all("Cannot use fix wall in periodic dimension"); + error->all(FLERR,"Cannot use fix wall in periodic dimension"); if ((wallwhich[m] == YLO || wallwhich[m] == YHI) && domain->yperiodic) - error->all("Cannot use fix wall in periodic dimension"); + error->all(FLERR,"Cannot use fix wall in periodic dimension"); if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->zperiodic) - error->all("Cannot use fix wall in periodic dimension"); + error->all(FLERR,"Cannot use fix wall in periodic dimension"); } for (int m = 0; m < nwall; m++) if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->dimension == 2) - error->all("Cannot use fix wall zlo/zhi for a 2d simulation"); + error->all(FLERR,"Cannot use fix wall zlo/zhi for a 2d simulation"); // scale coord for CONSTANT walls @@ -127,7 +127,7 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : if (flag) { if (scaleflag && domain->lattice == NULL) - error->all("Use of fix wall with undefined lattice"); + error->all(FLERR,"Use of fix wall with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -186,9 +186,9 @@ void FixWall::init() if (wallstyle[m] != VARIABLE) continue; varindex[m] = input->variable->find(varstr[m]); if (varindex[m] < 0) - error->all("Variable name for fix wall does not exist"); + error->all(FLERR,"Variable name for fix wall does not exist"); if (!input->variable->equalstyle(varindex[m])) - error->all("Variable for fix wall is invalid style"); + error->all(FLERR,"Variable for fix wall is invalid style"); } // setup coefficients diff --git a/src/fix_wall_harmonic.cpp b/src/fix_wall_harmonic.cpp index 4d0660a0f4..e7eb85b54c 100644 --- a/src/fix_wall_harmonic.cpp +++ b/src/fix_wall_harmonic.cpp @@ -61,5 +61,5 @@ void FixWallHarmonic::wall_particle(int m, int which, double coord) ewall[m+1] += fwall; } - if (onflag) error->one("Particle on or inside fix wall surface"); + if (onflag) error->one(FLERR,"Particle on or inside fix wall surface"); } diff --git a/src/fix_wall_lj126.cpp b/src/fix_wall_lj126.cpp index 132cea9c0b..47b0eba6f3 100644 --- a/src/fix_wall_lj126.cpp +++ b/src/fix_wall_lj126.cpp @@ -77,5 +77,5 @@ void FixWallLJ126::wall_particle(int m, int which, double coord) ewall[m+1] += fwall; } - if (onflag) error->one("Particle on or inside fix wall surface"); + if (onflag) error->one(FLERR,"Particle on or inside fix wall surface"); } diff --git a/src/fix_wall_lj93.cpp b/src/fix_wall_lj93.cpp index e106ec5e6a..0f8f9dff19 100644 --- a/src/fix_wall_lj93.cpp +++ b/src/fix_wall_lj93.cpp @@ -80,5 +80,5 @@ void FixWallLJ93::wall_particle(int m, int which, double coord) ewall[m+1] += fwall; } - if (onflag) error->one("Particle on or inside fix wall surface"); + if (onflag) error->one(FLERR,"Particle on or inside fix wall surface"); } diff --git a/src/fix_wall_reflect.cpp b/src/fix_wall_reflect.cpp index fa74faf48a..2251fd2662 100644 --- a/src/fix_wall_reflect.cpp +++ b/src/fix_wall_reflect.cpp @@ -34,7 +34,7 @@ enum{NONE,EDGE,CONSTANT,VARIABLE}; FixWallReflect::FixWallReflect(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 4) error->all("Illegal fix wall/reflect command"); + if (narg < 4) error->all(FLERR,"Illegal fix wall/reflect command"); // parse args @@ -46,7 +46,7 @@ FixWallReflect::FixWallReflect(LAMMPS *lmp, int narg, char **arg) : if ((strcmp(arg[iarg],"xlo") == 0) || (strcmp(arg[iarg],"xhi") == 0) || (strcmp(arg[iarg],"ylo") == 0) || (strcmp(arg[iarg],"yhi") == 0) || (strcmp(arg[iarg],"zlo") == 0) || (strcmp(arg[iarg],"zhi") == 0)) { - if (iarg+2 > narg) error->all("Illegal fix wall/reflect command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall/reflect command"); int newwall; if (strcmp(arg[iarg],"xlo") == 0) newwall = XLO; @@ -58,7 +58,7 @@ FixWallReflect::FixWallReflect(LAMMPS *lmp, int narg, char **arg) : for (int m = 0; m < nwall; m++) if (newwall == wallwhich[m]) - error->all("Wall defined twice in fix wall/reflect command"); + error->all(FLERR,"Wall defined twice in fix wall/reflect command"); wallwhich[nwall] = newwall; if (strcmp(arg[iarg+1],"EDGE") == 0) { @@ -81,30 +81,30 @@ FixWallReflect::FixWallReflect(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal wall/reflect command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal wall/reflect command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal fix wall/reflect command"); + else error->all(FLERR,"Illegal fix wall/reflect command"); iarg += 2; - } else error->all("Illegal fix wall/reflect command"); + } else error->all(FLERR,"Illegal fix wall/reflect command"); } // error check - if (nwall == 0) error->all("Illegal fix wall command"); + if (nwall == 0) error->all(FLERR,"Illegal fix wall command"); for (int m = 0; m < nwall; m++) { if ((wallwhich[m] == XLO || wallwhich[m] == XHI) && domain->xperiodic) - error->all("Cannot use fix wall/reflect in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/reflect in periodic dimension"); if ((wallwhich[m] == YLO || wallwhich[m] == YHI) && domain->yperiodic) - error->all("Cannot use fix wall/reflect in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/reflect in periodic dimension"); if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->zperiodic) - error->all("Cannot use fix wall/reflect in periodic dimension"); + error->all(FLERR,"Cannot use fix wall/reflect in periodic dimension"); } for (int m = 0; m < nwall; m++) if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->dimension == 2) - error->all("Cannot use fix wall/reflect zlo/zhi for a 2d simulation"); + error->all(FLERR,"Cannot use fix wall/reflect zlo/zhi for a 2d simulation"); // scale coord for CONSTANT walls @@ -114,7 +114,7 @@ FixWallReflect::FixWallReflect(LAMMPS *lmp, int narg, char **arg) : if (flag) { if (scaleflag && domain->lattice == NULL) - error->all("Use of fix wall with undefined lattice"); + error->all(FLERR,"Use of fix wall with undefined lattice"); double xscale,yscale,zscale; if (scaleflag) { @@ -166,9 +166,9 @@ void FixWallReflect::init() if (wallstyle[m] != VARIABLE) continue; varindex[m] = input->variable->find(varstr[m]); if (varindex[m] < 0) - error->all("Variable name for fix wall/reflect does not exist"); + error->all(FLERR,"Variable name for fix wall/reflect does not exist"); if (!input->variable->equalstyle(varindex[m])) - error->all("Variable for fix wall/reflect is invalid style"); + error->all(FLERR,"Variable for fix wall/reflect is invalid style"); } int nrigid = 0; @@ -176,7 +176,7 @@ void FixWallReflect::init() if (modify->fix[i]->rigid_flag) nrigid++; if (nrigid && comm->me == 0) - error->warning("Should not allow rigid bodies to bounce off " + error->warning(FLERR,"Should not allow rigid bodies to bounce off " "relecting walls"); } diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index c3e77cb5fe..151e20259d 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -34,7 +34,7 @@ enum{LJ93,LJ126,COLLOID,HARMONIC}; FixWallRegion::FixWallRegion(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 8) error->all("Illegal fix wall/region command"); + if (narg != 8) error->all(FLERR,"Illegal fix wall/region command"); scalar_flag = 1; vector_flag = 1; @@ -47,7 +47,7 @@ FixWallRegion::FixWallRegion(LAMMPS *lmp, int narg, char **arg) : iregion = domain->find_region(arg[3]); if (iregion == -1) - error->all("Region ID for fix wall/region does not exist"); + error->all(FLERR,"Region ID for fix wall/region does not exist"); int n = strlen(arg[3]) + 1; idregion = new char[n]; strcpy(idregion,arg[3]); @@ -56,13 +56,13 @@ FixWallRegion::FixWallRegion(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[4],"lj126") == 0) style = LJ126; else if (strcmp(arg[4],"colloid") == 0) style = COLLOID; else if (strcmp(arg[4],"harmonic") == 0) style = HARMONIC; - else error->all("Illegal fix wall/region command"); + else error->all(FLERR,"Illegal fix wall/region command"); epsilon = atof(arg[5]); sigma = atof(arg[6]); cutoff = atof(arg[7]); - if (cutoff <= 0.0) error->all("Fix wall/region cutoff <= 0.0"); + if (cutoff <= 0.0) error->all(FLERR,"Fix wall/region cutoff <= 0.0"); eflag = 0; ewall[0] = ewall[1] = ewall[2] = ewall[3] = 0.0; @@ -95,14 +95,14 @@ void FixWallRegion::init() iregion = domain->find_region(idregion); if (iregion == -1) - error->all("Region ID for fix wall/region does not exist"); + error->all(FLERR,"Region ID for fix wall/region does not exist"); // error checks for style COLLOID // insure all particles in group are extended particles if (style == COLLOID) { if (!atom->sphere_flag) - error->all("Fix wall/region colloid requires atom style sphere"); + error->all(FLERR,"Fix wall/region colloid requires atom style sphere"); double *radius = atom->radius; int *mask = atom->mask; @@ -116,7 +116,7 @@ void FixWallRegion::init() int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall) - error->all("Fix wall/region colloid requires extended particles"); + error->all(FLERR,"Fix wall/region colloid requires extended particles"); } // setup coefficients for each style @@ -231,7 +231,7 @@ void FixWallRegion::post_force(int vflag) } } - if (onflag) error->one("Particle on or inside surface of region " + if (onflag) error->one(FLERR,"Particle on or inside surface of region " "used in fix wall/region"); } diff --git a/src/force.cpp b/src/force.cpp index 2282b9a676..71511fc78f 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -38,9 +38,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Force::Force(LAMMPS *lmp) : Pointers(lmp) @@ -168,7 +165,7 @@ Pair *Force::new_pair(const char *style, char *suffix, int &sflag) #include "style_pair.h" #undef PAIR_CLASS - else error->all("Invalid pair style"); + else error->all(FLERR,"Invalid pair style"); return NULL; } @@ -247,7 +244,7 @@ Bond *Force::new_bond(const char *style) #include "style_bond.h" #undef BOND_CLASS - else error->all("Invalid bond style"); + else error->all(FLERR,"Invalid bond style"); return NULL; } @@ -295,7 +292,7 @@ Angle *Force::new_angle(const char *style) #include "style_angle.h" #undef ANGLE_CLASS - else error->all("Invalid angle style"); + else error->all(FLERR,"Invalid angle style"); return NULL; } @@ -328,7 +325,7 @@ Dihedral *Force::new_dihedral(const char *style) #include "style_dihedral.h" #undef DIHEDRAL_CLASS - else error->all("Invalid dihedral style"); + else error->all(FLERR,"Invalid dihedral style"); return NULL; } @@ -361,7 +358,7 @@ Improper *Force::new_improper(const char *style) #include "style_improper.h" #undef IMPROPER_CLASS - else error->all("Invalid improper style"); + else error->all(FLERR,"Invalid improper style"); return NULL; } @@ -382,7 +379,7 @@ void Force::create_kspace(int narg, char **arg) #include "style_kspace.h" #undef KSPACE_CLASS - else error->all("Invalid kspace style"); + else error->all(FLERR,"Invalid kspace style"); int n = strlen(arg[0]) + 1; kspace_style = new char[n]; @@ -395,12 +392,12 @@ void Force::create_kspace(int narg, char **arg) void Force::set_special(int narg, char **arg) { - if (narg == 0) error->all("Illegal special_bonds command"); + if (narg == 0) error->all(FLERR,"Illegal special_bonds command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"amber") == 0) { - if (iarg+1 > narg) error->all("Illegal special_bonds command"); + if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = 0.0; special_lj[2] = 0.0; special_lj[3] = 0.5; @@ -409,7 +406,7 @@ void Force::set_special(int narg, char **arg) special_coul[3] = 5.0/6.0; iarg += 1; } else if (strcmp(arg[iarg],"charmm") == 0) { - if (iarg+1 > narg) error->all("Illegal special_bonds command"); + if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = 0.0; special_lj[2] = 0.0; special_lj[3] = 0.0; @@ -418,7 +415,7 @@ void Force::set_special(int narg, char **arg) special_coul[3] = 0.0; iarg += 1; } else if (strcmp(arg[iarg],"dreiding") == 0) { - if (iarg+1 > narg) error->all("Illegal special_bonds command"); + if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = 0.0; special_lj[2] = 0.0; special_lj[3] = 1.0; @@ -427,7 +424,7 @@ void Force::set_special(int narg, char **arg) special_coul[3] = 1.0; iarg += 1; } else if (strcmp(arg[iarg],"fene") == 0) { - if (iarg+1 > narg) error->all("Illegal special_bonds command"); + if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = 0.0; special_lj[2] = 1.0; special_lj[3] = 1.0; @@ -436,48 +433,48 @@ void Force::set_special(int narg, char **arg) special_coul[3] = 1.0; iarg += 1; } else if (strcmp(arg[iarg],"lj/coul") == 0) { - if (iarg+4 > narg) error->all("Illegal special_bonds command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = special_coul[1] = atof(arg[iarg+1]); special_lj[2] = special_coul[2] = atof(arg[iarg+2]); special_lj[3] = special_coul[3] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"lj") == 0) { - if (iarg+4 > narg) error->all("Illegal special_bonds command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command"); special_lj[1] = atof(arg[iarg+1]); special_lj[2] = atof(arg[iarg+2]); special_lj[3] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"coul") == 0) { - if (iarg+4 > narg) error->all("Illegal special_bonds command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command"); special_coul[1] = atof(arg[iarg+1]); special_coul[2] = atof(arg[iarg+2]); special_coul[3] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"angle") == 0) { - if (iarg+2 > narg) error->all("Illegal special_bonds command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command"); if (strcmp(arg[iarg+1],"no") == 0) special_angle = 0; else if (strcmp(arg[iarg+1],"yes") == 0) special_angle = 1; - else error->all("Illegal special_bonds command"); + else error->all(FLERR,"Illegal special_bonds command"); iarg += 2; } else if (strcmp(arg[iarg],"dihedral") == 0) { - if (iarg+2 > narg) error->all("Illegal special_bonds command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command"); if (strcmp(arg[iarg+1],"no") == 0) special_dihedral = 0; else if (strcmp(arg[iarg+1],"yes") == 0) special_dihedral = 1; - else error->all("Illegal special_bonds command"); + else error->all(FLERR,"Illegal special_bonds command"); iarg += 2; } else if (strcmp(arg[iarg],"extra") == 0) { - if (iarg+2 > narg) error->all("Illegal special_bonds command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command"); special_extra = atoi(arg[iarg+1]); iarg += 2; - } else error->all("Illegal special_bonds command"); + } else error->all(FLERR,"Illegal special_bonds command"); } for (int i = 1; i <= 3; i++) if (special_lj[i] < 0.0 || special_lj[i] > 1.0 || special_coul[i] < 0.0 || special_coul[i] > 1.0) - error->all("Illegal special_bonds command"); + error->all(FLERR,"Illegal special_bonds command"); - if (special_extra < 0) error->all("Illegal special_bonds command"); + if (special_extra < 0) error->all(FLERR,"Illegal special_bonds command"); } /* ---------------------------------------------------------------------- @@ -524,7 +521,7 @@ double Force::numeric(char *str) if (isdigit(str[i])) continue; if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue; if (str[i] == 'e' || str[i] == 'E') continue; - error->all("Expected floating point parameter in " + error->all(FLERR,"Expected floating point parameter in " "input script or data file"); } @@ -542,7 +539,7 @@ int Force::inumeric(char *str) int n = strlen(str); for (int i = 0; i < n; i++) { if (isdigit(str[i]) || str[i] == '-' || str[i] == '+') continue; - error->all("Expected integer parameter in input script or data file"); + error->all(FLERR,"Expected integer parameter in input script or data file"); } return atoi(str); diff --git a/src/group.cpp b/src/group.cpp index 7ab12b35f3..5d6073bae0 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -38,9 +38,6 @@ enum{LT,LE,GT,GE,EQ,NEQ,BETWEEN}; #define BIG 1.0e20 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- initialize group memory ------------------------------------------------------------------------- */ @@ -87,27 +84,27 @@ void Group::assign(int narg, char **arg) int i; if (domain->box_exist == 0) - error->all("Group command before simulation box is defined"); - if (narg < 2) error->all("Illegal group command"); + error->all(FLERR,"Group command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal group command"); // delete the group if not being used elsewhere // clear mask of each atom assigned to this group if (strcmp(arg[1],"delete") == 0) { int igroup = find(arg[0]); - if (igroup == -1) error->all("Could not find group delete group ID"); - if (igroup == 0) error->all("Cannot delete group all"); + if (igroup == -1) error->all(FLERR,"Could not find group delete group ID"); + if (igroup == 0) error->all(FLERR,"Cannot delete group all"); for (i = 0; i < modify->nfix; i++) if (modify->fix[i]->igroup == igroup) - error->all("Cannot delete group currently used by a fix"); + error->all(FLERR,"Cannot delete group currently used by a fix"); for (i = 0; i < modify->ncompute; i++) if (modify->compute[i]->igroup == igroup) - error->all("Cannot delete group currently used by a compute"); + error->all(FLERR,"Cannot delete group currently used by a compute"); for (i = 0; i < output->ndump; i++) if (output->dump[i]->igroup == igroup) - error->all("Cannot delete group currently used by a dump"); + error->all(FLERR,"Cannot delete group currently used by a dump"); if (atom->firstgroupname && strcmp(arg[0],atom->firstgroupname) == 0) - error->all("Cannot delete group currently used by atom_modify first"); + error->all(FLERR,"Cannot delete group currently used by atom_modify first"); int *mask = atom->mask; int nlocal = atom->nlocal; @@ -127,7 +124,7 @@ void Group::assign(int narg, char **arg) int igroup = find(arg[0]); if (igroup == -1) { - if (ngroup == MAX_GROUP) error->all("Too many groups"); + if (ngroup == MAX_GROUP) error->all(FLERR,"Too many groups"); igroup = find_unused(); int n = strlen(arg[0]) + 1; names[igroup] = new char[n]; @@ -146,10 +143,10 @@ void Group::assign(int narg, char **arg) if (strcmp(arg[1],"region") == 0) { - if (narg != 3) error->all("Illegal group command"); + if (narg != 3) error->all(FLERR,"Illegal group command"); int iregion = domain->find_region(arg[2]); - if (iregion == -1) error->all("Group region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Group region ID does not exist"); domain->init(); for (i = 0; i < nlocal; i++) @@ -163,13 +160,13 @@ void Group::assign(int narg, char **arg) strcmp(arg[2],"<=") == 0 || strcmp(arg[2],">=") == 0 || strcmp(arg[2],"<>") == 0)) { - if (narg < 4 || narg > 5) error->all("Illegal group command"); + if (narg < 4 || narg > 5) error->all(FLERR,"Illegal group command"); int category,condition,bound1,bound2; if (strcmp(arg[1],"type") == 0) category = TYPE; else if (strcmp(arg[1],"molecule") == 0) category = MOLECULE; else if (strcmp(arg[1],"id") == 0) category = ID; - else error->all("Illegal group command"); + else error->all(FLERR,"Illegal group command"); if (strcmp(arg[2],"<") == 0) condition = LT; else if (strcmp(arg[2],"<=") == 0) condition = LE; @@ -178,13 +175,13 @@ void Group::assign(int narg, char **arg) else if (strcmp(arg[2],"==") == 0) condition = EQ; else if (strcmp(arg[2],"!=") == 0) condition = NEQ; else if (strcmp(arg[2],"<>") == 0) condition = BETWEEN; - else error->all("Illegal group command"); + else error->all(FLERR,"Illegal group command"); bound1 = atoi(arg[3]); bound2 = -1; if (condition == BETWEEN) { - if (narg != 5) error->all("Illegal group command"); + if (narg != 5) error->all(FLERR,"Illegal group command"); bound2 = atoi(arg[4]); } @@ -217,7 +214,7 @@ void Group::assign(int narg, char **arg) } else if (strcmp(arg[1],"type") == 0 || strcmp(arg[1],"molecule") == 0 || strcmp(arg[1],"id") == 0) { - if (narg < 3) error->all("Illegal group command"); + if (narg < 3) error->all(FLERR,"Illegal group command"); int length = narg-2; int *list = new int[length]; @@ -226,7 +223,7 @@ void Group::assign(int narg, char **arg) if (strcmp(arg[1],"type") == 0) category = TYPE; else if (strcmp(arg[1],"molecule") == 0) category = MOLECULE; else if (strcmp(arg[1],"id") == 0) category = ID; - else error->all("Illegal group command"); + else error->all(FLERR,"Illegal group command"); length = narg - 2; for (int iarg = 2; iarg < narg; iarg++) list[iarg-2] = atoi(arg[iarg]); @@ -248,7 +245,7 @@ void Group::assign(int narg, char **arg) } else if (strcmp(arg[1],"subtract") == 0) { - if (narg < 4) error->all("Illegal group command"); + if (narg < 4) error->all(FLERR,"Illegal group command"); int length = narg-2; int *list = new int[length]; @@ -256,7 +253,7 @@ void Group::assign(int narg, char **arg) int jgroup; for (int iarg = 2; iarg < narg; iarg++) { jgroup = find(arg[iarg]); - if (jgroup == -1) error->all("Group ID does not exist"); + if (jgroup == -1) error->all(FLERR,"Group ID does not exist"); list[iarg-2] = jgroup; } @@ -284,7 +281,7 @@ void Group::assign(int narg, char **arg) } else if (strcmp(arg[1],"union") == 0) { - if (narg < 3) error->all("Illegal group command"); + if (narg < 3) error->all(FLERR,"Illegal group command"); int length = narg-2; int *list = new int[length]; @@ -292,7 +289,7 @@ void Group::assign(int narg, char **arg) int jgroup; for (int iarg = 2; iarg < narg; iarg++) { jgroup = find(arg[iarg]); - if (jgroup == -1) error->all("Group ID does not exist"); + if (jgroup == -1) error->all(FLERR,"Group ID does not exist"); list[iarg-2] = jgroup; } @@ -312,7 +309,7 @@ void Group::assign(int narg, char **arg) } else if (strcmp(arg[1],"intersect") == 0) { - if (narg < 4) error->all("Illegal group command"); + if (narg < 4) error->all(FLERR,"Illegal group command"); int length = narg-2; int *list = new int[length]; @@ -320,7 +317,7 @@ void Group::assign(int narg, char **arg) int jgroup; for (int iarg = 2; iarg < narg; iarg++) { jgroup = find(arg[iarg]); - if (jgroup == -1) error->all("Group ID does not exist"); + if (jgroup == -1) error->all(FLERR,"Group ID does not exist"); list[iarg-2] = jgroup; } @@ -341,7 +338,7 @@ void Group::assign(int narg, char **arg) // not a valid group style - } else error->all("Illegal group command"); + } else error->all(FLERR,"Illegal group command"); // print stats for changed group @@ -374,7 +371,7 @@ void Group::create(char *name, int *flag) int igroup = find(name); if (igroup == -1) { - if (ngroup == MAX_GROUP) error->all("Too many groups"); + if (ngroup == MAX_GROUP) error->all(FLERR,"Too many groups"); igroup = find_unused(); int n = strlen(name) + 1; names[igroup] = new char[n]; diff --git a/src/improper.cpp b/src/improper.cpp index 7b82590d0a..3c65e8c89c 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -48,9 +48,9 @@ Improper::~Improper() void Improper::init() { - if (!allocated) error->all("Improper coeffs are not set"); + if (!allocated) error->all(FLERR,"Improper coeffs are not set"); for (int i = 1; i <= atom->nimpropertypes; i++) - if (setflag[i] == 0) error->all("All improper coeffs are not set"); + if (setflag[i] == 0) error->all(FLERR,"All improper coeffs are not set"); } /* ---------------------------------------------------------------------- diff --git a/src/input.cpp b/src/input.cpp index 05cb1f4412..bcabc02303 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -157,7 +157,7 @@ void Input::file() MPI_Bcast(&n,1,MPI_INT,0,world); if (n == 0) { - if (label_active) error->all("Label wasn't found in input script"); + if (label_active) error->all(FLERR,"Label wasn't found in input script"); if (me == 0) { if (infile != stdin) fclose(infile); nfile--; @@ -175,7 +175,7 @@ void Input::file() if (n == MAXLINE) { char str[MAXLINE+32]; sprintf(str,"Input line too long: %s",line); - error->all(str); + error->all(FLERR,str); } // echo the command unless scanning for label @@ -200,7 +200,7 @@ void Input::file() if (execute_command()) { char str[MAXLINE]; sprintf(str,"Unknown command: %s",line); - error->all(str); + error->all(FLERR,str); } } } @@ -217,13 +217,13 @@ void Input::file(const char *filename) if (me == 0) { if (nfile > 1) - error->one("Another input script is already being processed"); + error->one(FLERR,"Another input script is already being processed"); if (infile != stdin) fclose(infile); infile = fopen(filename,"r"); if (infile == NULL) { char str[128]; sprintf(str,"Cannot open input script %s",filename); - error->one(str); + error->one(FLERR,str); } infiles[0] = infile; } else infile = NULL; @@ -262,7 +262,7 @@ char *Input::one(const char *single) if (execute_command()) { char str[MAXLINE]; sprintf(str,"Unknown command: %s",line); - error->all(str); + error->all(FLERR,str); } return command; @@ -339,7 +339,7 @@ void Input::parse() narg++; } - if (quote) error->all("Unbalanced quotes in input line"); + if (quote) error->all(FLERR,"Unbalanced quotes in input line"); } /* ---------------------------------------------------------------------- @@ -367,7 +367,7 @@ void Input::substitute(char *str, int flag) var = ptr+2; int i = 0; while (var[i] != '\0' && var[i] != '}') i++; - if (var[i] == '\0') error->one("Invalid variable name"); + if (var[i] == '\0') error->one(FLERR,"Invalid variable name"); var[i] = '\0'; beyond = ptr + strlen(var) + 3; } else { @@ -377,15 +377,15 @@ void Input::substitute(char *str, int flag) beyond = ptr + strlen(var) + 1; } value = variable->retrieve(var); - if (value == NULL) error->one("Substitution for illegal variable"); + if (value == NULL) error->one(FLERR,"Substitution for illegal variable"); *ptr = '\0'; strcpy(work,str); if (strlen(work)+strlen(value) >= MAXLINE) - error->one("Input line too long after variable substitution"); + error->one(FLERR,"Input line too long after variable substitution"); strcat(work,value); if (strlen(work)+strlen(beyond) >= MAXLINE) - error->one("Input line too long after variable substitution"); + error->one(FLERR,"Input line too long after variable substitution"); strcat(work,beyond); strcpy(str,work); ptr += strlen(value); @@ -506,7 +506,7 @@ int Input::execute_command() void Input::clear() { - if (narg > 0) error->all("Illegal clear command"); + if (narg > 0) error->all(FLERR,"Illegal clear command"); lmp->destroy(); lmp->create(); } @@ -515,7 +515,7 @@ void Input::clear() void Input::echo() { - if (narg != 1) error->all("Illegal echo command"); + if (narg != 1) error->all(FLERR,"Illegal echo command"); if (strcmp(arg[0],"none") == 0) { echo_screen = 0; @@ -529,14 +529,14 @@ void Input::echo() } else if (strcmp(arg[0],"both") == 0) { echo_screen = 1; echo_log = 1; - } else error->all("Illegal echo command"); + } else error->all(FLERR,"Illegal echo command"); } /* ---------------------------------------------------------------------- */ void Input::ifthenelse() { - if (narg < 3) error->all("Illegal if command"); + if (narg < 3) error->all(FLERR,"Illegal if command"); // substitute for variables in Boolean expression for "if" // in case expression was enclosed in quotes @@ -552,7 +552,7 @@ void Input::ifthenelse() // bound "then" commands - if (strcmp(arg[1],"then") != 0) error->all("Illegal if command"); + if (strcmp(arg[1],"then") != 0) error->all(FLERR,"Illegal if command"); int first = 2; int iarg = first; @@ -567,13 +567,13 @@ void Input::ifthenelse() if (btest != 0.0) { int ncommands = last-first + 1; - if (ncommands <= 0) error->all("Illegal if command"); + if (ncommands <= 0) error->all(FLERR,"Illegal if command"); char **commands = new char*[ncommands]; ncommands = 0; for (int i = first; i <= last; i++) { int n = strlen(arg[i]) + 1; - if (n == 1) error->all("Illegal if command"); + if (n == 1) error->all(FLERR,"Illegal if command"); commands[ncommands] = new char[n]; strcpy(commands[ncommands],arg[i]); ncommands++; @@ -601,7 +601,7 @@ void Input::ifthenelse() // bound and execute "elif" or "else" commands while (1) { - if (iarg+2 > narg) error->all("Illegal if command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal if command"); if (strcmp(arg[iarg],"elif") == 0) { strcpy(scopy,arg[iarg+1]); substitute(scopy,0); @@ -621,13 +621,13 @@ void Input::ifthenelse() if (btest == 0.0) continue; int ncommands = last-first + 1; - if (ncommands <= 0) error->all("Illegal if command"); + if (ncommands <= 0) error->all(FLERR,"Illegal if command"); char **commands = new char*[ncommands]; ncommands = 0; for (int i = first; i <= last; i++) { int n = strlen(arg[i]) + 1; - if (n == 1) error->all("Illegal if command"); + if (n == 1) error->all(FLERR,"Illegal if command"); commands[ncommands] = new char[n]; strcpy(commands[ncommands],arg[i]); ncommands++; @@ -651,7 +651,7 @@ void Input::ifthenelse() void Input::include() { - if (narg != 1) error->all("Illegal include command"); + if (narg != 1) error->all(FLERR,"Illegal include command"); if (me == 0) { if (nfile == maxfile) { @@ -663,7 +663,7 @@ void Input::include() if (infile == NULL) { char str[128]; sprintf(str,"Cannot open input script %s",arg[0]); - error->one(str); + error->one(FLERR,str); } infiles[nfile++] = infile; } @@ -673,7 +673,7 @@ void Input::include() void Input::jump() { - if (narg < 1 || narg > 2) error->all("Illegal jump command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal jump command"); if (jump_skip) { jump_skip = 0; @@ -688,7 +688,7 @@ void Input::jump() if (infile == NULL) { char str[128]; sprintf(str,"Cannot open input script %s",arg[0]); - error->one(str); + error->one(FLERR,str); } infiles[nfile-1] = infile; } @@ -707,7 +707,7 @@ void Input::jump() void Input::label() { - if (narg != 1) error->all("Illegal label command"); + if (narg != 1) error->all(FLERR,"Illegal label command"); if (label_active && strcmp(labelstr,arg[0]) == 0) label_active = 0; } @@ -715,7 +715,7 @@ void Input::label() void Input::log() { - if (narg != 1) error->all("Illegal log command"); + if (narg != 1) error->all(FLERR,"Illegal log command"); if (me == 0) { if (logfile) fclose(logfile); @@ -725,7 +725,7 @@ void Input::log() if (logfile == NULL) { char str[128]; sprintf(str,"Cannot open logfile %s",arg[0]); - error->one(str); + error->one(FLERR,str); } } if (universe->nworlds == 1) universe->ulogfile = logfile; @@ -743,7 +743,7 @@ void Input::next_command() void Input::print() { - if (narg != 1) error->all("Illegal print command"); + if (narg != 1) error->all(FLERR,"Illegal print command"); // substitute for $ variables (no printing) and print arg @@ -758,14 +758,14 @@ void Input::print() void Input::shell() { - if (narg < 1) error->all("Illegal shell command"); + if (narg < 1) error->all(FLERR,"Illegal shell command"); if (strcmp(arg[0],"cd") == 0) { - if (narg != 2) error->all("Illegal shell command"); + if (narg != 2) error->all(FLERR,"Illegal shell command"); chdir(arg[1]); } else if (strcmp(arg[0],"mkdir") == 0) { - if (narg < 2) error->all("Illegal shell command"); + if (narg < 2) error->all(FLERR,"Illegal shell command"); #if !defined(WINDOWS) && !defined(__MINGW32_VERSION) if (me == 0) for (int i = 1; i < narg; i++) @@ -773,16 +773,16 @@ void Input::shell() #endif } else if (strcmp(arg[0],"mv") == 0) { - if (narg != 3) error->all("Illegal shell command"); + if (narg != 3) error->all(FLERR,"Illegal shell command"); if (me == 0) rename(arg[1],arg[2]); } else if (strcmp(arg[0],"rm") == 0) { - if (narg < 2) error->all("Illegal shell command"); + if (narg < 2) error->all(FLERR,"Illegal shell command"); if (me == 0) for (int i = 1; i < narg; i++) unlink(arg[i]); } else if (strcmp(arg[0],"rmdir") == 0) { - if (narg < 2) error->all("Illegal shell command"); + if (narg < 2) error->all(FLERR,"Illegal shell command"); if (me == 0) for (int i = 1; i < narg; i++) rmdir(arg[i]); @@ -819,11 +819,11 @@ void Input::variable_command() void Input::angle_coeff() { if (domain->box_exist == 0) - error->all("Angle_coeff command before simulation box is defined"); + error->all(FLERR,"Angle_coeff command before simulation box is defined"); if (force->angle == NULL) - error->all("Angle_coeff command before angle_style is defined"); + error->all(FLERR,"Angle_coeff command before angle_style is defined"); if (atom->avec->angles_allow == 0) - error->all("Angle_coeff command when no angles allowed"); + error->all(FLERR,"Angle_coeff command when no angles allowed"); force->angle->coeff(narg,arg); } @@ -831,9 +831,9 @@ void Input::angle_coeff() void Input::angle_style() { - if (narg < 1) error->all("Illegal angle_style command"); + if (narg < 1) error->all(FLERR,"Illegal angle_style command"); if (atom->avec->angles_allow == 0) - error->all("Angle_style command when no angles allowed"); + error->all(FLERR,"Angle_style command when no angles allowed"); force->create_angle(arg[0]); if (force->angle) force->angle->settings(narg-1,&arg[1]); } @@ -849,9 +849,9 @@ void Input::atom_modify() void Input::atom_style() { - if (narg < 1) error->all("Illegal atom_style command"); + if (narg < 1) error->all(FLERR,"Illegal atom_style command"); if (domain->box_exist) - error->all("Atom_style command after simulation box is defined"); + error->all(FLERR,"Atom_style command after simulation box is defined"); atom->create_avec(arg[0],narg-1,&arg[1],lmp->suffix); } @@ -860,11 +860,11 @@ void Input::atom_style() void Input::bond_coeff() { if (domain->box_exist == 0) - error->all("Bond_coeff command before simulation box is defined"); + error->all(FLERR,"Bond_coeff command before simulation box is defined"); if (force->bond == NULL) - error->all("Bond_coeff command before bond_style is defined"); + error->all(FLERR,"Bond_coeff command before bond_style is defined"); if (atom->avec->bonds_allow == 0) - error->all("Bond_coeff command when no bonds allowed"); + error->all(FLERR,"Bond_coeff command when no bonds allowed"); force->bond->coeff(narg,arg); } @@ -872,9 +872,9 @@ void Input::bond_coeff() void Input::bond_style() { - if (narg < 1) error->all("Illegal bond_style command"); + if (narg < 1) error->all(FLERR,"Illegal bond_style command"); if (atom->avec->bonds_allow == 0) - error->all("Bond_style command when no bonds allowed"); + error->all(FLERR,"Bond_style command when no bonds allowed"); force->create_bond(arg[0]); if (force->bond) force->bond->settings(narg-1,&arg[1]); } @@ -884,7 +884,7 @@ void Input::bond_style() void Input::boundary() { if (domain->box_exist) - error->all("Boundary command after simulation box is defined"); + error->all(FLERR,"Boundary command after simulation box is defined"); domain->set_boundary(narg,arg); } @@ -913,7 +913,7 @@ void Input::compute_modify() void Input::dielectric() { - if (narg != 1) error->all("Illegal dielectric command"); + if (narg != 1) error->all(FLERR,"Illegal dielectric command"); force->dielectric = atof(arg[0]); } @@ -922,11 +922,11 @@ void Input::dielectric() void Input::dihedral_coeff() { if (domain->box_exist == 0) - error->all("Dihedral_coeff command before simulation box is defined"); + error->all(FLERR,"Dihedral_coeff command before simulation box is defined"); if (force->dihedral == NULL) - error->all("Dihedral_coeff command before dihedral_style is defined"); + error->all(FLERR,"Dihedral_coeff command before dihedral_style is defined"); if (atom->avec->dihedrals_allow == 0) - error->all("Dihedral_coeff command when no dihedrals allowed"); + error->all(FLERR,"Dihedral_coeff command when no dihedrals allowed"); force->dihedral->coeff(narg,arg); } @@ -934,9 +934,9 @@ void Input::dihedral_coeff() void Input::dihedral_style() { - if (narg < 1) error->all("Illegal dihedral_style command"); + if (narg < 1) error->all(FLERR,"Illegal dihedral_style command"); if (atom->avec->dihedrals_allow == 0) - error->all("Dihedral_style command when no dihedrals allowed"); + error->all(FLERR,"Dihedral_style command when no dihedrals allowed"); force->create_dihedral(arg[0]); if (force->dihedral) force->dihedral->settings(narg-1,&arg[1]); } @@ -945,12 +945,12 @@ void Input::dihedral_style() void Input::dimension() { - if (narg != 1) error->all("Illegal dimension command"); + if (narg != 1) error->all(FLERR,"Illegal dimension command"); if (domain->box_exist) - error->all("Dimension command after simulation box is defined"); + error->all(FLERR,"Dimension command after simulation box is defined"); domain->dimension = atoi(arg[0]); if (domain->dimension != 2 && domain->dimension != 3) - error->all("Illegal dimension command"); + error->all(FLERR,"Illegal dimension command"); // must reset default extra_dof of all computes // since some were created before dimension command is encountered @@ -999,11 +999,11 @@ void Input::group_command() void Input::improper_coeff() { if (domain->box_exist == 0) - error->all("Improper_coeff command before simulation box is defined"); + error->all(FLERR,"Improper_coeff command before simulation box is defined"); if (force->improper == NULL) - error->all("Improper_coeff command before improper_style is defined"); + error->all(FLERR,"Improper_coeff command before improper_style is defined"); if (atom->avec->impropers_allow == 0) - error->all("Improper_coeff command when no impropers allowed"); + error->all(FLERR,"Improper_coeff command when no impropers allowed"); force->improper->coeff(narg,arg); } @@ -1011,9 +1011,9 @@ void Input::improper_coeff() void Input::improper_style() { - if (narg < 1) error->all("Illegal improper_style command"); + if (narg < 1) error->all(FLERR,"Illegal improper_style command"); if (atom->avec->impropers_allow == 0) - error->all("Improper_style command when no impropers allowed"); + error->all(FLERR,"Improper_style command when no impropers allowed"); force->create_improper(arg[0]); if (force->improper) force->improper->settings(narg-1,&arg[1]); } @@ -1022,7 +1022,7 @@ void Input::improper_style() void Input::kspace_modify() { - if (force->kspace == NULL) error->all("KSpace style has not yet been set"); + if (force->kspace == NULL) error->all(FLERR,"KSpace style has not yet been set"); force->kspace->modify_params(narg,arg); } @@ -1044,9 +1044,9 @@ void Input::lattice() void Input::mass() { - if (narg != 2) error->all("Illegal mass command"); + if (narg != 2) error->all(FLERR,"Illegal mass command"); if (domain->box_exist == 0) - error->all("Mass command before simulation box is defined"); + error->all(FLERR,"Mass command before simulation box is defined"); atom->set_mass(narg,arg); } @@ -1062,7 +1062,7 @@ void Input::min_modify() void Input::min_style() { if (domain->box_exist == 0) - error->all("Min_style command before simulation box is defined"); + error->all(FLERR,"Min_style command before simulation box is defined"); update->create_minimize(narg,arg); } @@ -1089,25 +1089,25 @@ void Input::newton() if (narg == 1) { if (strcmp(arg[0],"off") == 0) newton_pair = newton_bond = 0; else if (strcmp(arg[0],"on") == 0) newton_pair = newton_bond = 1; - else error->all("Illegal newton command"); + else error->all(FLERR,"Illegal newton command"); } else if (narg == 2) { if (strcmp(arg[0],"off") == 0) newton_pair = 0; else if (strcmp(arg[0],"on") == 0) newton_pair= 1; - else error->all("Illegal newton command"); + else error->all(FLERR,"Illegal newton command"); if (strcmp(arg[1],"off") == 0) newton_bond = 0; else if (strcmp(arg[1],"on") == 0) newton_bond = 1; - else error->all("Illegal newton command"); - } else error->all("Illegal newton command"); + else error->all(FLERR,"Illegal newton command"); + } else error->all(FLERR,"Illegal newton command"); force->newton_pair = newton_pair; if (newton_bond == 0) { if (domain->box_exist && force->newton_bond == 1) - error->all("Newton bond change after simulation box is defined"); + error->all(FLERR,"Newton bond change after simulation box is defined"); force->newton_bond = 0; } else { if (domain->box_exist && force->newton_bond == 0) - error->all("Newton bond change after simulation box is defined"); + error->all(FLERR,"Newton bond change after simulation box is defined"); force->newton_bond = 1; } @@ -1120,12 +1120,12 @@ void Input::newton() void Input::package() { if (domain->box_exist) - error->all("Package command after simulation box is defined"); - if (narg < 1) error->all("Illegal package command"); + error->all(FLERR,"Package command after simulation box is defined"); + if (narg < 1) error->all(FLERR,"Illegal package command"); if (strcmp(arg[0],"cuda") == 0) { if (!lmp->cuda) - error->all("Package cuda command without USER-CUDA installed"); + error->all(FLERR,"Package cuda command without USER-CUDA installed"); lmp->cuda->accelerator(narg-1,&arg[1]); } else if (strcmp(arg[0],"gpu") == 0) { @@ -1142,9 +1142,9 @@ void Input::package() } else if (strcmp(arg[0],"omp") == 0) { #ifdef _OPENMP - if (narg != 2) error->all("Illegal package command"); + if (narg != 2) error->all(FLERR,"Illegal package command"); comm->nthreads = atoi(arg[1]); - if (comm->nthreads < 1) error->all("Illegal package command"); + if (comm->nthreads < 1) error->all(FLERR,"Illegal package command"); omp_set_num_threads(comm->nthreads); if (me == 0) { @@ -1156,10 +1156,10 @@ void Input::package() comm->nthreads); } #else - error->all("Cannot use package omp command with no OpenMP support"); + error->all(FLERR,"Cannot use package omp command with no OpenMP support"); #endif - } else error->all("Illegal package command"); + } else error->all(FLERR,"Illegal package command"); } /* ---------------------------------------------------------------------- */ @@ -1167,9 +1167,9 @@ void Input::package() void Input::pair_coeff() { if (domain->box_exist == 0) - error->all("Pair_coeff command before simulation box is defined"); + error->all(FLERR,"Pair_coeff command before simulation box is defined"); if (force->pair == NULL) - error->all("Pair_coeff command before pair_style is defined"); + error->all(FLERR,"Pair_coeff command before pair_style is defined"); force->pair->coeff(narg,arg); } @@ -1178,7 +1178,7 @@ void Input::pair_coeff() void Input::pair_modify() { if (force->pair == NULL) - error->all("Pair_modify command before pair_style is defined"); + error->all(FLERR,"Pair_modify command before pair_style is defined"); force->pair->modify_params(narg,arg); } @@ -1189,7 +1189,7 @@ void Input::pair_modify() void Input::pair_style() { - if (narg < 1) error->all("Illegal pair_style command"); + if (narg < 1) error->all(FLERR,"Illegal pair_style command"); if (force->pair && strcmp(arg[0],force->pair_style) == 0) { force->pair->settings(narg-1,&arg[1]); return; @@ -1203,7 +1203,7 @@ void Input::pair_style() void Input::pair_write() { if (force->pair == NULL) - error->all("Pair_write command before pair_style is defined"); + error->all(FLERR,"Pair_write command before pair_style is defined"); force->pair->write_file(narg,arg); } @@ -1211,9 +1211,9 @@ void Input::pair_write() void Input::processors() { - if (narg != 3) error->all("Illegal processors command"); + if (narg != 3) error->all(FLERR,"Illegal processors command"); if (domain->box_exist) - error->all("Processors command after simulation box is defined"); + error->all(FLERR,"Processors command after simulation box is defined"); if (strcmp(arg[0],"*") == 0) comm->user_procgrid[0] = 0; else comm->user_procgrid[0] = atoi(arg[0]); @@ -1223,7 +1223,7 @@ void Input::processors() else comm->user_procgrid[2] = atoi(arg[2]); if (comm->user_procgrid[0] < 0 || comm->user_procgrid[1] < 0 || - comm->user_procgrid[2] < 0) error->all("Illegal processors command"); + comm->user_procgrid[2] < 0) error->all(FLERR,"Illegal processors command"); } /* ---------------------------------------------------------------------- */ @@ -1252,7 +1252,7 @@ void Input::restart() void Input::run_style() { if (domain->box_exist == 0) - error->all("Run_style command before simulation box is defined"); + error->all(FLERR,"Run_style command before simulation box is defined"); update->create_integrate(narg,arg,lmp->suffix); } @@ -1291,7 +1291,7 @@ void Input::special_bonds() void Input::suffix() { - if (narg != 1) error->all("Illegal suffix command"); + if (narg != 1) error->all(FLERR,"Illegal suffix command"); if (strcmp(arg[0],"off") == 0) lmp->suffix_enable = 0; else if (strcmp(arg[0],"on") == 0) lmp->suffix_enable = 1; @@ -1308,7 +1308,7 @@ void Input::suffix() void Input::thermo() { - if (narg != 1) error->all("Illegal thermo command"); + if (narg != 1) error->all(FLERR,"Illegal thermo command"); output->thermo_every = atoi(arg[0]); } @@ -1330,7 +1330,7 @@ void Input::thermo_style() void Input::timestep() { - if (narg != 1) error->all("Illegal timestep command"); + if (narg != 1) error->all(FLERR,"Illegal timestep command"); update->dt = atof(arg[0]); } @@ -1338,7 +1338,7 @@ void Input::timestep() void Input::uncompute() { - if (narg != 1) error->all("Illegal uncompute command"); + if (narg != 1) error->all(FLERR,"Illegal uncompute command"); modify->delete_compute(arg[0]); } @@ -1346,7 +1346,7 @@ void Input::uncompute() void Input::undump() { - if (narg != 1) error->all("Illegal undump command"); + if (narg != 1) error->all(FLERR,"Illegal undump command"); output->delete_dump(arg[0]); } @@ -1354,7 +1354,7 @@ void Input::undump() void Input::unfix() { - if (narg != 1) error->all("Illegal unfix command"); + if (narg != 1) error->all(FLERR,"Illegal unfix command"); modify->delete_fix(arg[0]); } @@ -1362,8 +1362,8 @@ void Input::unfix() void Input::units() { - if (narg != 1) error->all("Illegal units command"); + if (narg != 1) error->all(FLERR,"Illegal units command"); if (domain->box_exist) - error->all("Units command after simulation box is defined"); + error->all(FLERR,"Units command after simulation box is defined"); update->set_units(arg[0]); } diff --git a/src/irregular.cpp b/src/irregular.cpp index d9abe11b88..fe801ae45e 100644 --- a/src/irregular.cpp +++ b/src/irregular.cpp @@ -28,9 +28,6 @@ using namespace LAMMPS_NS; #define BUFMIN 1000 #define BUFEXTRA 1000 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Irregular::Irregular(LAMMPS *lmp) : Pointers(lmp) diff --git a/src/kspace.cpp b/src/kspace.cpp index c0613140d3..116535f8ee 100644 --- a/src/kspace.cpp +++ b/src/kspace.cpp @@ -40,7 +40,7 @@ void KSpace::modify_params(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"mesh") == 0) { - if (iarg+4 > narg) error->all("Illegal kspace_modify command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal kspace_modify command"); nx_pppm = atoi(arg[iarg+1]); ny_pppm = atoi(arg[iarg+2]); nz_pppm = atoi(arg[iarg+3]); @@ -48,26 +48,26 @@ void KSpace::modify_params(int narg, char **arg) else gridflag = 1; iarg += 4; } else if (strcmp(arg[iarg],"order") == 0) { - if (iarg+2 > narg) error->all("Illegal kspace_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command"); order = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"gewald") == 0) { - if (iarg+2 > narg) error->all("Illegal kspace_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command"); g_ewald = atof(arg[iarg+1]); if (g_ewald == 0.0) gewaldflag = 0; else gewaldflag = 1; iarg += 2; } else if (strcmp(arg[iarg],"slab") == 0) { - if (iarg+2 > narg) error->all("Illegal kspace_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command"); slab_volfactor = atof(arg[iarg+1]); iarg += 2; if (slab_volfactor <= 1.0) - error->all("Bad kspace_modify slab parameter"); + error->all(FLERR,"Bad kspace_modify slab parameter"); if (slab_volfactor < 2.0 && comm->me == 0) - error->warning("Kspace_modify slab param < 2.0 may " + error->warning(FLERR,"Kspace_modify slab param < 2.0 may " "cause unphysical behavior"); slabflag = 1; - } else error->all("Illegal kspace_modify command"); + } else error->all(FLERR,"Illegal kspace_modify command"); } } diff --git a/src/lammps.cpp b/src/lammps.cpp index e5342c1e31..09b6a487de 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -81,7 +81,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) if (strcmp(arg[iarg],"-partition") == 0 || strcmp(arg[iarg],"-p") == 0) { universe->existflag = 1; - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); iarg++; while (iarg < narg && arg[iarg][0] != '-') { universe->add_world(arg[iarg]); @@ -89,50 +89,50 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) } } else if (strcmp(arg[iarg],"-in") == 0 || strcmp(arg[iarg],"-i") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); inflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-screen") == 0 || strcmp(arg[iarg],"-sc") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); screenflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-log") == 0 || strcmp(arg[iarg],"-l") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); logflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-var") == 0 || strcmp(arg[iarg],"-v") == 0) { - if (iarg+3 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+3 > narg) error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; while (iarg < narg && arg[iarg][0] != '-') iarg++; } else if (strcmp(arg[iarg],"-echo") == 0 || strcmp(arg[iarg],"-e") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-pscreen") == 0 || strcmp(arg[iarg],"-ps") == 0) { if (iarg+2 > narg) - error->universe_all("Invalid command-line argument"); + error->universe_all(FLERR,"Invalid command-line argument"); partscreenflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-plog") == 0 || strcmp(arg[iarg],"-pl") == 0) { if (iarg+2 > narg) - error->universe_all("Invalid command-line argument"); + error->universe_all(FLERR,"Invalid command-line argument"); partlogflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-cuda") == 0 || strcmp(arg[iarg],"-c") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); if (strcmp(arg[iarg+1],"on") == 0) cudaflag = 1; else if (strcmp(arg[iarg+1],"off") == 0) cudaflag = 0; - else error->universe_all("Invalid command-line argument"); + else error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-suffix") == 0 || strcmp(arg[iarg],"-sf") == 0) { - if (iarg+2 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); delete [] suffix; int n = strlen(arg[iarg+1]) + 1; suffix = new char[n]; @@ -141,10 +141,10 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) iarg += 2; } else if (strcmp(arg[iarg],"-help") == 0 || strcmp(arg[iarg],"-h") == 0) { - if (iarg+1 > narg) error->universe_all("Invalid command-line argument"); + if (iarg+1 > narg) error->universe_all(FLERR,"Invalid command-line argument"); helpflag = 1; iarg += 1; - } else error->universe_all("Invalid command-line argument"); + } else error->universe_all(FLERR,"Invalid command-line argument"); } // if no partition command-line switch, universe is one world w/ all procs @@ -154,22 +154,22 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) // sum of procs in all worlds must equal total # of procs if (!universe->consistent()) - error->universe_all("Processor partitions are inconsistent"); + error->universe_all(FLERR,"Processor partitions are inconsistent"); // universe cannot use stdin for input file if (universe->existflag && inflag == 0) - error->universe_all("Must use -in switch with multiple partitions"); + error->universe_all(FLERR,"Must use -in switch with multiple partitions"); // if no partition command-line switch, cannot use -pscreen option if (universe->existflag == 0 && partscreenflag) - error->universe_all("Can only use -pscreen with multiple partitions"); + error->universe_all(FLERR,"Can only use -pscreen with multiple partitions"); // if no partition command-line switch, cannot use -plog option if (universe->existflag == 0 && partlogflag) - error->universe_all("Can only use -plog with multiple partitions"); + error->universe_all(FLERR,"Can only use -plog with multiple partitions"); // set universe screen and logfile @@ -181,18 +181,18 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) else { universe->uscreen = fopen(arg[screenflag],"w"); if (universe->uscreen == NULL) - error->universe_one("Cannot open universe screen file"); + error->universe_one(FLERR,"Cannot open universe screen file"); } if (logflag == 0) { universe->ulogfile = fopen("log.lammps","w"); if (universe->ulogfile == NULL) - error->universe_one("Cannot open log.lammps"); + error->universe_one(FLERR,"Cannot open log.lammps"); } else if (strcmp(arg[logflag],"none") == 0) universe->ulogfile = NULL; else { universe->ulogfile = fopen(arg[logflag],"w"); if (universe->ulogfile == NULL) - error->universe_one("Cannot open universe log file"); + error->universe_one(FLERR,"Cannot open universe log file"); } } @@ -219,7 +219,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) if (infile == NULL) { char str[128]; sprintf(str,"Cannot open input script %s",arg[inflag]); - error->one(str); + error->one(FLERR,str); } } @@ -244,14 +244,14 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) char str[32]; sprintf(str,"screen.%d",universe->iworld); screen = fopen(str,"w"); - if (screen == NULL) error->one("Cannot open screen file"); + if (screen == NULL) error->one(FLERR,"Cannot open screen file"); } else if (strcmp(arg[screenflag],"none") == 0) screen = NULL; else { char str[128]; sprintf(str,"%s.%d",arg[screenflag],universe->iworld); screen = fopen(str,"w"); - if (screen == NULL) error->one("Cannot open screen file"); + if (screen == NULL) error->one(FLERR,"Cannot open screen file"); } else if (strcmp(arg[partscreenflag],"none") == 0) screen = NULL; @@ -259,7 +259,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) char str[128]; sprintf(str,"%s.%d",arg[partscreenflag],universe->iworld); screen = fopen(str,"w"); - if (screen == NULL) error->one("Cannot open screen file"); + if (screen == NULL) error->one(FLERR,"Cannot open screen file"); } else screen = NULL; if (me == 0) @@ -268,14 +268,14 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) char str[32]; sprintf(str,"log.lammps.%d",universe->iworld); logfile = fopen(str,"w"); - if (logfile == NULL) error->one("Cannot open logfile"); + if (logfile == NULL) error->one(FLERR,"Cannot open logfile"); } else if (strcmp(arg[logflag],"none") == 0) logfile = NULL; else { char str[128]; sprintf(str,"%s.%d",arg[logflag],universe->iworld); logfile = fopen(str,"w"); - if (logfile == NULL) error->one("Cannot open logfile"); + if (logfile == NULL) error->one(FLERR,"Cannot open logfile"); } else if (strcmp(arg[partlogflag],"none") == 0) logfile = NULL; @@ -283,7 +283,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) char str[128]; sprintf(str,"%s.%d",arg[partlogflag],universe->iworld); logfile = fopen(str,"w"); - if (logfile == NULL) error->one("Cannot open logfile"); + if (logfile == NULL) error->one(FLERR,"Cannot open logfile"); } else logfile = NULL; if (me == 0) { @@ -291,7 +291,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) if (infile == NULL) { char str[128]; sprintf(str,"Cannot open input script %s",arg[inflag]); - error->one(str); + error->one(FLERR,str); } } else infile = NULL; @@ -325,34 +325,34 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) // check datatype settings in lmptype.h if (sizeof(smallint) != sizeof(int)) - error->all("Smallint setting in lmptype.h is invalid"); + error->all(FLERR,"Smallint setting in lmptype.h is invalid"); if (sizeof(tagint) < sizeof(smallint)) - error->all("Tagint setting in lmptype.h is invalid"); + error->all(FLERR,"Tagint setting in lmptype.h is invalid"); if (sizeof(bigint) < sizeof(tagint)) - error->all("Bigint setting in lmptype.h is invalid"); + error->all(FLERR,"Bigint setting in lmptype.h is invalid"); int mpisize; MPI_Type_size(MPI_LMP_TAGINT,&mpisize); if (mpisize != sizeof(tagint)) - error->all("MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); + error->all(FLERR,"MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); MPI_Type_size(MPI_LMP_BIGINT,&mpisize); if (mpisize != sizeof(bigint)) - error->all("MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); + error->all(FLERR,"MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); #ifdef LAMMPS_SMALLBIG if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 8) - error->all("Small, tag, big integers are not sized correctly"); + error->all(FLERR,"Small, tag, big integers are not sized correctly"); #endif #ifdef LAMMPS_BIGBIG if (sizeof(smallint) != 4 || sizeof(tagint) != 8 || sizeof(bigint) != 8) - error->all("Small, tag, big integers are not sized correctly"); + error->all(FLERR,"Small, tag, big integers are not sized correctly"); #endif #ifdef LAMMPS_SMALLSMALL if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 4) - error->all("Small, tag, big integers are not sized correctly"); + error->all(FLERR,"Small, tag, big integers are not sized correctly"); #endif - if (sizeof(tagint) == 8) error->all("64-bit atom IDs are not yet supported"); + if (sizeof(tagint) == 8) error->all(FLERR,"64-bit atom IDs are not yet supported"); // create CUDA class if USER-CUDA installed, unless explicitly switched off // instantiation creates dummy CUDA class if USER-CUDA is not installed @@ -362,7 +362,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) } else if (cudaflag == 1) { cuda = new Cuda(this); if (!cuda->cuda_exists) - error->all("Cannot use -cuda on without USER-CUDA installed"); + error->all(FLERR,"Cannot use -cuda on without USER-CUDA installed"); } else { cuda = new Cuda(this); if (!cuda->cuda_exists) { @@ -373,7 +373,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) int me; MPI_Comm_rank(world,&me); - if (cuda && me == 0) error->message("USER-CUDA mode is enabled"); + if (cuda && me == 0) error->message(FLERR,"USER-CUDA mode is enabled"); // allocate input class now that MPI is fully setup diff --git a/src/lattice.cpp b/src/lattice.cpp index 48e749834c..196074deb8 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -23,8 +23,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) #define BIG 1.0e30 enum{NONE,SC,BCC,FCC,HCP,DIAMOND,SQ,SQ2,HEX,CUSTOM}; @@ -38,7 +36,7 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) // parse style arg - if (narg < 1) error->all("Illegal lattice command"); + if (narg < 1) error->all(FLERR,"Illegal lattice command"); if (strcmp(arg[0],"none") == 0) style = NONE; else if (strcmp(arg[0],"sc") == 0) style = SC; @@ -50,10 +48,10 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) else if (strcmp(arg[0],"sq2") == 0) style = SQ2; else if (strcmp(arg[0],"hex") == 0) style = HEX; else if (strcmp(arg[0],"custom") == 0) style = CUSTOM; - else error->all("Illegal lattice command"); + else error->all(FLERR,"Illegal lattice command"); if (style == NONE) { - if (narg > 1) error->all("Illegal lattice command"); + if (narg > 1) error->all(FLERR,"Illegal lattice command"); return; } @@ -64,18 +62,18 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) if (dimension == 2) { if (style == SC || style == BCC || style == FCC || style == HCP || style == DIAMOND) - error->all("Lattice style incompatible with simulation dimension"); + error->all(FLERR,"Lattice style incompatible with simulation dimension"); } if (dimension == 3) { if (style == SQ || style == SQ2 || style == HEX) - error->all("Lattice style incompatible with simulation dimension"); + error->all(FLERR,"Lattice style incompatible with simulation dimension"); } // scale = conversion factor between lattice and box units - if (narg < 2) error->all("Illegal lattice command"); + if (narg < 2) error->all(FLERR,"Illegal lattice command"); scale = atof(arg[1]); - if (scale <= 0.0) error->all("Illegal lattice command"); + if (scale <= 0.0) error->all(FLERR,"Illegal lattice command"); // set basis atoms for each style // x,y,z = fractional coords within unit cell @@ -140,23 +138,23 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) int iarg = 2; while (iarg < narg) { if (strcmp(arg[iarg],"origin") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); origin[0] = atof(arg[iarg+1]); origin[1] = atof(arg[iarg+2]); origin[2] = atof(arg[iarg+3]); if (origin[0] < 0.0 || origin[0] >= 1.0 || origin[1] < 0.0 || origin[1] >= 1.0 || origin[2] < 0.0 || origin[2] >= 1.0) - error->all("Illegal lattice command"); + error->all(FLERR,"Illegal lattice command"); iarg += 4; } else if (strcmp(arg[iarg],"orient") == 0) { - if (iarg+5 > narg) error->all("Illegal lattice command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal lattice command"); int dim; if (strcmp(arg[iarg+1],"x") == 0) dim = 0; else if (strcmp(arg[iarg+1],"y") == 0) dim = 1; else if (strcmp(arg[iarg+1],"z") == 0) dim = 2; - else error->all("Illegal lattice command"); + else error->all(FLERR,"Illegal lattice command"); int *orient; if (dim == 0) orient = orientx; else if (dim == 1) orient = orienty; @@ -167,7 +165,7 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) iarg += 5; } else if (strcmp(arg[iarg],"spacing") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); spaceflag = 1; xlattice = atof(arg[iarg+1]); ylattice = atof(arg[iarg+2]); @@ -175,67 +173,67 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) iarg += 4; } else if (strcmp(arg[iarg],"a1") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); if (style != CUSTOM) - error->all("Invalid option in lattice command for non-custom style"); + error->all(FLERR,"Invalid option in lattice command for non-custom style"); a1[0] = atof(arg[iarg+1]); a1[1] = atof(arg[iarg+2]); a1[2] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"a2") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); if (style != CUSTOM) - error->all("Invalid option in lattice command for non-custom style"); + error->all(FLERR,"Invalid option in lattice command for non-custom style"); a2[0] = atof(arg[iarg+1]); a2[1] = atof(arg[iarg+2]); a2[2] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"a3") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); if (style != CUSTOM) - error->all("Invalid option in lattice command for non-custom style"); + error->all(FLERR,"Invalid option in lattice command for non-custom style"); a3[0] = atof(arg[iarg+1]); a3[1] = atof(arg[iarg+2]); a3[2] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"basis") == 0) { - if (iarg+4 > narg) error->all("Illegal lattice command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal lattice command"); if (style != CUSTOM) - error->all("Invalid option in lattice command for non-custom style"); + error->all(FLERR,"Invalid option in lattice command for non-custom style"); double x = atof(arg[iarg+1]); double y = atof(arg[iarg+2]); double z = atof(arg[iarg+3]); if (x < 0.0 || x >= 1.0 || y < 0.0 || y >= 1.0 || z < 0.0 || z >= 1.0) - error->all("Illegal lattice command"); + error->all(FLERR,"Illegal lattice command"); add_basis(x,y,z); iarg += 4; - } else error->all("Illegal lattice command"); + } else error->all(FLERR,"Illegal lattice command"); } // check settings for errors - if (nbasis == 0) error->all("No basis atoms in lattice"); + if (nbasis == 0) error->all(FLERR,"No basis atoms in lattice"); if (!orthogonal()) - error->all("Lattice orient vectors are not orthogonal"); + error->all(FLERR,"Lattice orient vectors are not orthogonal"); if (!right_handed()) - error->all("Lattice orient vectors are not right-handed"); + error->all(FLERR,"Lattice orient vectors are not right-handed"); if (collinear()) - error->all("Lattice primitive vectors are collinear"); + error->all(FLERR,"Lattice primitive vectors are collinear"); if (dimension == 2) { if (origin[2] != 0.0) - error->all("Lattice settings are not compatible with 2d simulation"); + error->all(FLERR,"Lattice settings are not compatible with 2d simulation"); if (orientx[2] != 0 || orienty[2] != 0 || orientz[0] != 0 || orientz[1] != 0) - error->all("Lattice settings are not compatible with 2d simulation"); + error->all(FLERR,"Lattice settings are not compatible with 2d simulation"); if (a1[2] != 0.0 || a2[2] != 0.0 || a3[0] != 0.0 || a3[1] != 0.0) - error->all("Lattice settings are not compatible with 2d simulation"); + error->all(FLERR,"Lattice settings are not compatible with 2d simulation"); } if (spaceflag) { if (xlattice <= 0.0 || ylattice <= 0.0 || zlattice <= 0.0) - error->all("Lattice spacings are invalid"); + error->all(FLERR,"Lattice spacings are invalid"); } // reset scale for LJ units (input scale is rho*) @@ -376,7 +374,7 @@ void Lattice::setup_transform() primitive[0][1]*primitive[1][0]*primitive[2][2] - primitive[0][2]*primitive[1][1]*primitive[2][0]; - if (determinant == 0.0) error->all("Degenerate lattice primitive vectors"); + if (determinant == 0.0) error->all(FLERR,"Degenerate lattice primitive vectors"); priminv[0][0] = (primitive[1][1]*primitive[2][2] - primitive[1][2]*primitive[2][1]) / determinant; @@ -404,7 +402,7 @@ void Lattice::setup_transform() int lensq = orientx[0]*orientx[0] + orientx[1]*orientx[1] + orientx[2]*orientx[2]; length = sqrt((double) lensq); - if (length == 0.0) error->all("Zero-length lattice orient vector"); + if (length == 0.0) error->all(FLERR,"Zero-length lattice orient vector"); rotaterow[0][0] = orientx[0] / length; rotaterow[0][1] = orientx[1] / length; @@ -413,7 +411,7 @@ void Lattice::setup_transform() lensq = orienty[0]*orienty[0] + orienty[1]*orienty[1] + orienty[2]*orienty[2]; length = sqrt((double) lensq); - if (length == 0.0) error->all("Zero-length lattice orient vector"); + if (length == 0.0) error->all(FLERR,"Zero-length lattice orient vector"); rotaterow[1][0] = orienty[0] / length; rotaterow[1][1] = orienty[1] / length; @@ -422,7 +420,7 @@ void Lattice::setup_transform() lensq = orientz[0]*orientz[0] + orientz[1]*orientz[1] + orientz[2]*orientz[2]; length = sqrt((double) lensq); - if (length == 0.0) error->all("Zero-length lattice orient vector"); + if (length == 0.0) error->all(FLERR,"Zero-length lattice orient vector"); rotaterow[2][0] = orientz[0] / length; rotaterow[2][1] = orientz[1] / length; diff --git a/src/memory.cpp b/src/memory.cpp index 6af16e68e0..11e15f10e5 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -37,7 +37,7 @@ void *Memory::smalloc(bigint nbytes, const char *name) char str[128]; sprintf(str,"Failed to allocate " BIGINT_FORMAT " bytes for array %s", nbytes,name); - error->one(str); + error->one(FLERR,str); } return ptr; } @@ -58,7 +58,7 @@ void *Memory::srealloc(void *ptr, bigint nbytes, const char *name) char str[128]; sprintf(str,"Failed to reallocate " BIGINT_FORMAT " bytes for array %s", nbytes,name); - error->one(str); + error->one(FLERR,str); } return ptr; } @@ -81,5 +81,5 @@ void Memory::fail(const char *name) { char str[128]; sprintf(str,"Cannot create/grow a vector/array of pointers for %s",name); - error->one(str); + error->one(FLERR,str); } diff --git a/src/min.cpp b/src/min.cpp index 55253f11e8..bf83065261 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -47,9 +47,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ Min::Min(LAMMPS *lmp) : Pointers(lmp) @@ -160,7 +157,7 @@ void Min::init() if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) { if (comm->me == 0) - error->warning("Resetting reneighboring criteria during minimization"); + error->warning(FLERR,"Resetting reneighboring criteria during minimization"); } neighbor->every = 1; @@ -191,7 +188,7 @@ void Min::setup() // compute for potential energy int id = modify->find_compute("thermo_pe"); - if (id < 0) error->all("Minimization could not find thermo_pe compute"); + if (id < 0) error->all(FLERR,"Minimization could not find thermo_pe compute"); pe_compute = modify->compute[id]; // style-specific setup does two tasks @@ -230,9 +227,9 @@ void Min::setup() // remove these restriction eventually if (nextra_global && searchflag == 0) - error->all("Cannot use a damped dynamics min style with fix box/relax"); + error->all(FLERR,"Cannot use a damped dynamics min style with fix box/relax"); if (nextra_atom && searchflag == 0) - error->all("Cannot use a damped dynamics min style with per-atom DOF"); + error->all(FLERR,"Cannot use a damped dynamics min style with per-atom DOF"); // atoms may have migrated in comm->exchange() @@ -584,21 +581,21 @@ int Min::request(Pair *pair, int peratom, double maxvalue) void Min::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal min_modify command"); + if (narg == 0) error->all(FLERR,"Illegal min_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"dmax") == 0) { - if (iarg+2 > narg) error->all("Illegal min_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); dmax = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"line") == 0) { - if (iarg+2 > narg) error->all("Illegal min_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); if (strcmp(arg[iarg+1],"backtrack") == 0) linestyle = 0; else if (strcmp(arg[iarg+1],"quadratic") == 0) linestyle = 1; - else error->all("Illegal min_modify command"); + else error->all(FLERR,"Illegal min_modify command"); iarg += 2; - } else error->all("Illegal min_modify command"); + } else error->all(FLERR,"Illegal min_modify command"); } } diff --git a/src/min_cg.cpp b/src/min_cg.cpp index 9ef3c8c4a7..f2b1a666f5 100644 --- a/src/min_cg.cpp +++ b/src/min_cg.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ MinCG::MinCG(LAMMPS *lmp) : MinLineSearch(lmp) {} diff --git a/src/min_fire.cpp b/src/min_fire.cpp index 0c4e73dc26..18081f17b5 100644 --- a/src/min_fire.cpp +++ b/src/min_fire.cpp @@ -31,9 +31,6 @@ using namespace LAMMPS_NS; enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELAYSTEP 5 #define DT_GROW 1.1 #define DT_SHRINK 0.5 diff --git a/src/min_hftn.cpp b/src/min_hftn.cpp index 99c8cef3b6..da92ade46d 100644 --- a/src/min_hftn.cpp +++ b/src/min_hftn.cpp @@ -28,9 +28,6 @@ #include "update.h" #include "timer.h" -#define MIN(A,B) (((A) < (B)) ? (A) : (B)) -#define MAX(A,B) (((A) > (B)) ? (A) : (B)) - using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- diff --git a/src/min_linesearch.cpp b/src/min_linesearch.cpp index f3ae5782a4..1736b066e2 100644 --- a/src/min_linesearch.cpp +++ b/src/min_linesearch.cpp @@ -53,9 +53,6 @@ using namespace LAMMPS_NS; enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ MinLineSearch::MinLineSearch(LAMMPS *lmp) : Min(lmp) diff --git a/src/min_quickmin.cpp b/src/min_quickmin.cpp index 5ed10f8634..fe9df160b5 100644 --- a/src/min_quickmin.cpp +++ b/src/min_quickmin.cpp @@ -33,9 +33,6 @@ using namespace LAMMPS_NS; enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define DELAYSTEP 5 /* ---------------------------------------------------------------------- */ diff --git a/src/minimize.cpp b/src/minimize.cpp index dcee996dc0..f93fbf5385 100644 --- a/src/minimize.cpp +++ b/src/minimize.cpp @@ -31,10 +31,10 @@ Minimize::Minimize(LAMMPS *lmp) : Pointers(lmp) {} void Minimize::command(int narg, char **arg) { - if (narg != 4) error->all("Illegal minimize command"); + if (narg != 4) error->all(FLERR,"Illegal minimize command"); if (domain->box_exist == 0) - error->all("Minimize command before simulation box is defined"); + error->all(FLERR,"Minimize command before simulation box is defined"); update->etol = atof(arg[0]); update->ftol = atof(arg[1]); @@ -42,13 +42,13 @@ void Minimize::command(int narg, char **arg) update->max_eval = atoi(arg[3]); if (update->etol < 0.0 || update->ftol < 0.0) - error->all("Illegal minimize command"); + error->all(FLERR,"Illegal minimize command"); update->whichflag = 2; update->beginstep = update->firststep = update->ntimestep; update->endstep = update->laststep = update->firststep + update->nsteps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many iterations"); + error->all(FLERR,"Too many iterations"); lmp->init(); update->minimize->setup(); diff --git a/src/modify.cpp b/src/modify.cpp index afad1579aa..c07416ac44 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -53,9 +53,6 @@ using namespace LAMMPS_NS; #define MIN_ENERGY 131072 #define POST_RUN 262144 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ @@ -240,7 +237,7 @@ void Modify::init() int checkall; MPI_Allreduce(&check,&checkall,1,MPI_INT,MPI_SUM,world); if (comm->me == 0 && checkall) - error->warning("One or more atoms are time integrated more than once"); + error->warning(FLERR,"One or more atoms are time integrated more than once"); } /* ---------------------------------------------------------------------- @@ -595,13 +592,13 @@ int Modify::min_reset_ref() void Modify::add_fix(int narg, char **arg, char *suffix) { if (domain->box_exist == 0 && allow_early_fix == 0) - error->all("Fix command before simulation box is defined"); - if (narg < 3) error->all("Illegal fix command"); + error->all(FLERR,"Fix command before simulation box is defined"); + if (narg < 3) error->all(FLERR,"Illegal fix command"); // check group ID int igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find fix group ID"); + if (igroup == -1) error->all(FLERR,"Could not find fix group ID"); // if fix ID exists: // set newflag = 0 so create new fix in same location in fix list @@ -623,9 +620,9 @@ void Modify::add_fix(int narg, char **arg, char *suffix) if (ifix < nfix) { newflag = 0; if (strcmp(arg[2],fix[ifix]->style) != 0) - error->all("Replacing a fix, but new style != old style"); + error->all(FLERR,"Replacing a fix, but new style != old style"); if (fix[ifix]->igroup != igroup && comm->me == 0) - error->warning("Replacing a fix, but new group != old group"); + error->warning(FLERR,"Replacing a fix, but new group != old group"); delete fix[ifix]; fix[ifix] = NULL; } else { @@ -668,7 +665,7 @@ void Modify::add_fix(int narg, char **arg, char *suffix) #undef FixStyle #undef FIX_CLASS - else error->all("Invalid fix style"); + else error->all(FLERR,"Invalid fix style"); } // set fix mask values and increment nfix (if new) @@ -714,14 +711,14 @@ void Modify::add_fix(int narg, char **arg, char *suffix) void Modify::modify_fix(int narg, char **arg) { - if (narg < 2) error->all("Illegal fix_modify command"); + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); // lookup Fix ID int ifix; for (ifix = 0; ifix < nfix; ifix++) if (strcmp(arg[0],fix[ifix]->id) == 0) break; - if (ifix == nfix) error->all("Could not find fix_modify ID"); + if (ifix == nfix) error->all(FLERR,"Could not find fix_modify ID"); fix[ifix]->modify_params(narg-1,&arg[1]); } @@ -734,7 +731,7 @@ void Modify::modify_fix(int narg, char **arg) void Modify::delete_fix(const char *id) { int ifix = find_fix(id); - if (ifix < 0) error->all("Could not find fix ID to delete"); + if (ifix < 0) error->all(FLERR,"Could not find fix ID to delete"); delete fix[ifix]; atom->update_callback(ifix); @@ -765,13 +762,13 @@ int Modify::find_fix(const char *id) void Modify::add_compute(int narg, char **arg, char *suffix) { - if (narg < 3) error->all("Illegal compute command"); + if (narg < 3) error->all(FLERR,"Illegal compute command"); // error check for (int icompute = 0; icompute < ncompute; icompute++) if (strcmp(arg[0],compute[icompute]->id) == 0) - error->all("Reuse of compute ID"); + error->all(FLERR,"Reuse of compute ID"); // extend Compute list if necessary @@ -814,7 +811,7 @@ void Modify::add_compute(int narg, char **arg, char *suffix) #undef ComputeStyle #undef COMPUTE_CLASS - else error->all("Invalid compute style"); + else error->all(FLERR,"Invalid compute style"); } ncompute++; @@ -826,14 +823,14 @@ void Modify::add_compute(int narg, char **arg, char *suffix) void Modify::modify_compute(int narg, char **arg) { - if (narg < 2) error->all("Illegal compute_modify command"); + if (narg < 2) error->all(FLERR,"Illegal compute_modify command"); // lookup Compute ID int icompute; for (icompute = 0; icompute < ncompute; icompute++) if (strcmp(arg[0],compute[icompute]->id) == 0) break; - if (icompute == ncompute) error->all("Could not find compute_modify ID"); + if (icompute == ncompute) error->all(FLERR,"Could not find compute_modify ID"); compute[icompute]->modify_params(narg-1,&arg[1]); } @@ -845,7 +842,7 @@ void Modify::modify_compute(int narg, char **arg) void Modify::delete_compute(char *id) { int icompute = find_compute(id); - if (icompute < 0) error->all("Could not find compute ID to delete"); + if (icompute < 0) error->all(FLERR,"Could not find compute ID to delete"); delete compute[icompute]; // move other Computes down in list one slot diff --git a/src/neigh_bond.cpp b/src/neigh_bond.cpp index b16598011e..f9ff7f07e0 100644 --- a/src/neigh_bond.cpp +++ b/src/neigh_bond.cpp @@ -46,7 +46,7 @@ void Neighbor::bond_all() sprintf(str, "Bond atoms %d %d missing on proc %d at step " BIGINT_FORMAT, tag[i],bond_atom[i][m],me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || i < atom1) { if (nbondlist == maxbond) { @@ -85,7 +85,7 @@ void Neighbor::bond_partial() sprintf(str, "Bond atoms %d %d missing on proc %d at step " BIGINT_FORMAT, tag[i],bond_atom[i][m],me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || i < atom1) { if (nbondlist == maxbond) { @@ -128,7 +128,7 @@ void Neighbor::angle_all() BIGINT_FORMAT, angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { if (nanglelist == maxangle) { @@ -173,7 +173,7 @@ void Neighbor::angle_partial() BIGINT_FORMAT, angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { if (nanglelist == maxangle) { @@ -220,7 +220,7 @@ void Neighbor::dihedral_all() dihedral_atom1[i][m],dihedral_atom2[i][m], dihedral_atom3[i][m],dihedral_atom4[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { @@ -270,7 +270,7 @@ void Neighbor::dihedral_partial() dihedral_atom1[i][m],dihedral_atom2[i][m], dihedral_atom3[i][m],dihedral_atom4[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { @@ -319,7 +319,7 @@ void Neighbor::improper_all() improper_atom1[i][m],improper_atom2[i][m], improper_atom3[i][m],improper_atom4[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { @@ -369,7 +369,7 @@ void Neighbor::improper_partial() improper_atom1[i][m],improper_atom2[i][m], improper_atom3[i][m],improper_atom4[i][m], me,update->ntimestep); - error->one(str); + error->one(FLERR,str); } if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { diff --git a/src/neigh_derive.cpp b/src/neigh_derive.cpp index c3d3eb0245..21e7c0c6c1 100644 --- a/src/neigh_derive.cpp +++ b/src/neigh_derive.cpp @@ -73,7 +73,7 @@ void Neighbor::half_from_full_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -151,7 +151,7 @@ void Neighbor::half_from_full_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -224,7 +224,7 @@ void Neighbor::skip_from(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -326,7 +326,7 @@ void Neighbor::skip_from_granular(NeighList *list) firstshear[i] = shearptr; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -465,20 +465,20 @@ void Neighbor::skip_from_respa(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } } diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp index c667ab6160..b4b7fd0aeb 100644 --- a/src/neigh_full.cpp +++ b/src/neigh_full.cpp @@ -99,7 +99,7 @@ void Neighbor::full_nsq(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -201,7 +201,7 @@ void Neighbor::full_nsq_ghost(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = atom->nlocal; @@ -295,7 +295,7 @@ void Neighbor::full_bin(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -423,7 +423,7 @@ void Neighbor::full_bin_ghost(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = atom->nlocal; @@ -525,7 +525,7 @@ void Neighbor::full_multi(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"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 ce75b16afc..7e7c282f5c 100644 --- a/src/neigh_gran.cpp +++ b/src/neigh_gran.cpp @@ -157,7 +157,7 @@ void Neighbor::granular_nsq_no_newton(NeighList *list) } npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -255,7 +255,7 @@ void Neighbor::granular_nsq_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -409,7 +409,7 @@ void Neighbor::granular_bin_no_newton(NeighList *list) } npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -519,7 +519,7 @@ void Neighbor::granular_bin_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -617,7 +617,7 @@ void Neighbor::granular_bin_newton_tri(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; diff --git a/src/neigh_half_bin.cpp b/src/neigh_half_bin.cpp index e776b82030..e1487897f7 100644 --- a/src/neigh_half_bin.cpp +++ b/src/neigh_half_bin.cpp @@ -109,7 +109,7 @@ void Neighbor::half_bin_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -228,7 +228,7 @@ void Neighbor::half_bin_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -331,7 +331,7 @@ void Neighbor::half_bin_newton_tri(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; diff --git a/src/neigh_half_multi.cpp b/src/neigh_half_multi.cpp index d0a8efcd2b..04e25931be 100644 --- a/src/neigh_half_multi.cpp +++ b/src/neigh_half_multi.cpp @@ -117,7 +117,7 @@ void Neighbor::half_multi_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -246,7 +246,7 @@ void Neighbor::half_multi_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -359,7 +359,7 @@ void Neighbor::half_multi_newton_tri(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; diff --git a/src/neigh_half_nsq.cpp b/src/neigh_half_nsq.cpp index 1df4865984..32792a678f 100644 --- a/src/neigh_half_nsq.cpp +++ b/src/neigh_half_nsq.cpp @@ -99,7 +99,7 @@ void Neighbor::half_nsq_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; @@ -203,7 +203,7 @@ void Neighbor::half_nsq_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } list->inum = inum; diff --git a/src/neigh_respa.cpp b/src/neigh_respa.cpp index a5190316ff..8e1e7b79e0 100644 --- a/src/neigh_respa.cpp +++ b/src/neigh_respa.cpp @@ -151,14 +151,14 @@ void Neighbor::respa_nsq_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { ilist_middle[inum] = i; @@ -166,7 +166,7 @@ void Neighbor::respa_nsq_no_newton(NeighList *list) numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } inum++; @@ -328,14 +328,14 @@ void Neighbor::respa_nsq_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { ilist_middle[inum] = i; @@ -343,7 +343,7 @@ void Neighbor::respa_nsq_newton(NeighList *list) numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } inum++; @@ -498,14 +498,14 @@ void Neighbor::respa_bin_no_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { ilist_middle[inum] = i; @@ -513,7 +513,7 @@ void Neighbor::respa_bin_no_newton(NeighList *list) numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } inum++; @@ -703,14 +703,14 @@ void Neighbor::respa_bin_newton(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { ilist_middle[inum] = i; @@ -718,7 +718,7 @@ void Neighbor::respa_bin_newton(NeighList *list) numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } inum++; @@ -880,14 +880,14 @@ void Neighbor::respa_bin_newton_tri(NeighList *list) numneigh[i] = n; npnt += n; if (n > oneatom || npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; npnt_inner += n_inner; if (npnt_inner >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); if (respamiddle) { ilist_middle[inum] = i; @@ -895,7 +895,7 @@ void Neighbor::respa_bin_newton_tri(NeighList *list) numneigh_middle[i] = n_middle; npnt_middle += n_middle; if (npnt_middle >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page"); } inum++; diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 141841d80d..58f8ad94dd 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -49,9 +49,6 @@ using namespace LAMMPS_NS; #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_list.cpp //#define NEIGH_LIST_DEBUG 1 @@ -196,10 +193,10 @@ void Neighbor::init() // error check if (delay > 0 && (delay % every) != 0) - error->all("Neighbor delay must be 0 or multiple of every setting"); + error->all(FLERR,"Neighbor delay must be 0 or multiple of every setting"); if (pgsize < 10*oneatom) - error->all("Neighbor page size must be >= 10x the one atom setting"); + error->all(FLERR,"Neighbor page size must be >= 10x the one atom setting"); // ------------------------------------------------------------------ // settings @@ -382,7 +379,7 @@ void Neighbor::init() for (i = 0; i < nex_type; i++) { if (ex1_type[i] <= 0 || ex1_type[i] > n || ex2_type[i] <= 0 || ex2_type[i] > n) - error->all("Invalid atom type in neighbor exclusion list"); + error->all(FLERR,"Invalid atom type in neighbor exclusion list"); ex_type[ex1_type[i]][ex2_type[i]] = 1; ex_type[ex2_type[i]][ex1_type[i]] = 1; } @@ -857,16 +854,16 @@ void Neighbor::choose_build(int index, NeighRequest *rq) if (style == NSQ) { if (rq->ghost == 0) pb = &Neighbor::full_nsq; else if (includegroup) - error->all("Neighbor include group not allowed with ghost neighbors"); + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost; } else if (style == BIN) { if (rq->ghost == 0) pb = &Neighbor::full_bin; else if (includegroup) - error->all("Neighbor include group not allowed with ghost neighbors"); + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost; } else if (style == MULTI) { if (rq->ghost == 0) pb = &Neighbor::full_multi; - else error->all("Neighbor multi not yet enabled for ghost neighbors"); + else error->all(FLERR,"Neighbor multi not yet enabled for ghost neighbors"); } } else if (rq->gran) { @@ -878,7 +875,7 @@ void Neighbor::choose_build(int index, NeighRequest *rq) 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"); + error->all(FLERR,"Neighbor multi not yet enabled for granular"); } else if (rq->respaouter) { if (style == NSQ) { @@ -889,13 +886,13 @@ void Neighbor::choose_build(int index, NeighRequest *rq) 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"); + error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); } // general error check if (rq->ghost && !rq->full) - error->all("Neighbors of ghost atoms only allowed for full neighbor lists"); + error->all(FLERR,"Neighbors of ghost atoms only allowed for full neighbor lists"); pair_build[index] = pb; } @@ -1181,7 +1178,7 @@ void Neighbor::build() // check that neighbor list with special bond flags will not overflow if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one("Too many local+ghost atoms for neighbor list"); + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); // invoke building of pair and molecular neighbor lists // only for pairwise lists with buildflag set @@ -1224,7 +1221,7 @@ void Neighbor::build_one(int i) // check that neighbor list with special bond flags will not overflow if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one("Too many local+ghost atoms for neighbor list"); + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); // when occasional list built, LAMMPS can crash if atoms have moved too far // why is this?, give warning if this is the case @@ -1235,7 +1232,7 @@ void Neighbor::build_one(int i) int flag = 0; if (dist_check && update->whichflag) flag = check_distance(); if (flag && me == 0) - error->warning("Building an occasional neighobr list when " + error->warning(FLERR,"Building an occasional neighobr list when " "atoms may have moved too far"); (this->*pair_build[i])(lists[i]); @@ -1313,7 +1310,7 @@ void Neighbor::setup_bins() if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || bbox[2]*binsizeinv > MAXSMALLINT) - error->all("Domain too large for neighbor bins"); + error->all(FLERR,"Domain too large for neighbor bins"); // create actual bins // always have one bin even if cutoff > bbox @@ -1345,7 +1342,7 @@ void Neighbor::setup_bins() if (binsize_optimal*bininvx > CUT2BIN_RATIO || binsize_optimal*bininvy > CUT2BIN_RATIO || binsize_optimal*bininvz > CUT2BIN_RATIO) - error->all("Cannot use neighbor bins - box size << cutoff"); + error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); // mbinlo/hi = lowest and highest global bins my ghost atoms could be in // coord = lowest and highest values of coords for my ghost atoms @@ -1395,7 +1392,7 @@ void Neighbor::setup_bins() // memory for bin ptrs bigint bbin = mbinx*mbiny*mbinz; - if (bbin > MAXSMALLINT) error->one("Too many neighbor bins"); + if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins"); mbins = bbin; if (mbins > maxhead) { maxhead = mbins; @@ -1455,15 +1452,15 @@ double Neighbor::bin_distance(int i, int j, int k) void Neighbor::set(int narg, char **arg) { - if (narg != 2) error->all("Illegal neighbor command"); + if (narg != 2) error->all(FLERR,"Illegal neighbor command"); skin = atof(arg[0]); - if (skin < 0.0) error->all("Illegal neighbor command"); + if (skin < 0.0) error->all(FLERR,"Illegal neighbor command"); if (strcmp(arg[1],"nsq") == 0) style = NSQ; else if (strcmp(arg[1],"bin") == 0) style = BIN; else if (strcmp(arg[1],"multi") == 0) style = MULTI; - else error->all("Illegal neighbor command"); + else error->all(FLERR,"Illegal neighbor command"); } /* ---------------------------------------------------------------------- @@ -1475,55 +1472,55 @@ void Neighbor::modify_params(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"every") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); every = atoi(arg[iarg+1]); - if (every <= 0) error->all("Illegal neigh_modify command"); + if (every <= 0) error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"delay") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); delay = atoi(arg[iarg+1]); - if (delay < 0) error->all("Illegal neigh_modify command"); + if (delay < 0) error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"check") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) dist_check = 1; else if (strcmp(arg[iarg+1],"no") == 0) dist_check = 0; - else error->all("Illegal neigh_modify command"); + else error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"once") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) build_once = 1; else if (strcmp(arg[iarg+1],"no") == 0) build_once = 0; - else error->all("Illegal neigh_modify command"); + else error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"page") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); pgsize = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"one") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); oneatom = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"binsize") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); binsize_user = atof(arg[iarg+1]); if (binsize_user <= 0.0) binsizeflag = 0; else binsizeflag = 1; iarg += 2; } else if (strcmp(arg[iarg],"include") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); includegroup = group->find(arg[iarg+1]); if (includegroup < 0) - error->all("Invalid group ID in neigh_modify command"); + error->all(FLERR,"Invalid group ID in neigh_modify command"); if (includegroup && (atom->firstgroupname == NULL || strcmp(arg[iarg+1],atom->firstgroupname) != 0)) - error->all("Neigh_modify include group != atom_modify first group"); + error->all(FLERR,"Neigh_modify include group != atom_modify first group"); iarg += 2; } else if (strcmp(arg[iarg],"exclude") == 0) { - if (iarg+2 > narg) error->all("Illegal neigh_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"type") == 0) { - if (iarg+4 > narg) error->all("Illegal neigh_modify command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (nex_type == maxex_type) { maxex_type += EXDELTA; memory->grow(ex1_type,maxex_type,"neigh:ex1_type"); @@ -1535,7 +1532,7 @@ void Neighbor::modify_params(int narg, char **arg) iarg += 4; } else if (strcmp(arg[iarg+1],"group") == 0) { - if (iarg+4 > narg) error->all("Illegal neigh_modify command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (nex_group == maxex_group) { maxex_group += EXDELTA; memory->grow(ex1_group,maxex_group,"neigh:ex1_group"); @@ -1544,16 +1541,16 @@ void Neighbor::modify_params(int narg, char **arg) ex1_group[nex_group] = group->find(arg[iarg+2]); ex2_group[nex_group] = group->find(arg[iarg+3]); if (ex1_group[nex_group] == -1 || ex2_group[nex_group] == -1) - error->all("Invalid group ID in neigh_modify command"); + error->all(FLERR,"Invalid group ID in neigh_modify command"); nex_group++; iarg += 4; } else if (strcmp(arg[iarg+1],"molecule") == 0) { - if (iarg+3 > narg) error->all("Illegal neigh_modify command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (atom->molecule_flag == 0) { char *str = (char *) "Neigh_modify exclude molecule requires atom attribute molecule"; - error->all(str); + error->all(FLERR,str); } if (nex_mol == maxex_mol) { maxex_mol += EXDELTA; @@ -1561,16 +1558,16 @@ void Neighbor::modify_params(int narg, char **arg) } ex_mol_group[nex_mol] = group->find(arg[iarg+2]); if (ex_mol_group[nex_mol] == -1) - error->all("Invalid group ID in neigh_modify command"); + error->all(FLERR,"Invalid group ID in neigh_modify command"); nex_mol++; iarg += 3; } else if (strcmp(arg[iarg+1],"none") == 0) { nex_type = nex_group = nex_mol = 0; iarg += 2; - } else error->all("Illegal neigh_modify command"); + } else error->all(FLERR,"Illegal neigh_modify command"); - } else error->all("Illegal neigh_modify command"); + } else error->all(FLERR,"Illegal neigh_modify command"); } } diff --git a/src/output.cpp b/src/output.cpp index de7ed5baa6..50a7cc008b 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -125,9 +125,9 @@ void Output::init() else if (var_thermo) { ivar_thermo = input->variable->find(var_thermo); if (ivar_thermo < 0) - error->all("Variable name for thermo every does not exist"); + error->all(FLERR,"Variable name for thermo every does not exist"); if (!input->variable->equalstyle(ivar_thermo)) - error->all("Variable for thermo every is invalid style"); + error->all(FLERR,"Variable for thermo every is invalid style"); } for (int i = 0; i < ndump; i++) dump[i]->init(); @@ -135,9 +135,9 @@ void Output::init() if (every_dump[i] == 0) { ivar_dump[i] = input->variable->find(var_dump[i]); if (ivar_dump[i] < 0) - error->all("Variable name for dump every does not exist"); + error->all(FLERR,"Variable name for dump every does not exist"); if (!input->variable->equalstyle(ivar_dump[i])) - error->all("Variable for dump every is invalid style"); + error->all(FLERR,"Variable for dump every is invalid style"); } } @@ -180,7 +180,7 @@ void Output::setup(int flag) int nextdump = static_cast (input->variable->compute_equal(ivar_dump[idump])); if (nextdump <= ntimestep) - error->all("Dump every variable returned a bad timestep"); + error->all(FLERR,"Dump every variable returned a bad timestep"); next_dump[idump] = nextdump; } if (dump[idump]->clearstep) { @@ -223,7 +223,7 @@ void Output::setup(int flag) next_thermo = static_cast (input->variable->compute_equal(ivar_thermo)); if (next_thermo <= ntimestep) - error->all("Thermo every variable returned a bad timestep"); + error->all(FLERR,"Thermo every variable returned a bad timestep"); } else next_thermo = update->laststep; modify->addstep_compute(next_thermo); @@ -260,7 +260,7 @@ void Output::write(bigint ntimestep) int nextdump = static_cast (input->variable->compute_equal(ivar_dump[idump])); if (nextdump <= ntimestep) - error->all("Dump every variable returned a bad timestep"); + error->all(FLERR,"Dump every variable returned a bad timestep"); next_dump[idump] = nextdump; } if (dump[idump]->clearstep) modify->addstep_compute(next_dump[idump]); @@ -309,7 +309,7 @@ void Output::write(bigint ntimestep) next_thermo = static_cast (input->variable->compute_equal(ivar_thermo)); if (next_thermo <= ntimestep) - error->all("Thermo every variable returned a bad timestep"); + error->all(FLERR,"Thermo every variable returned a bad timestep"); } else next_thermo = update->laststep; next_thermo = MYMIN(next_thermo,update->laststep); modify->addstep_compute(next_thermo); @@ -364,15 +364,15 @@ void Output::write_restart(bigint ntimestep) void Output::add_dump(int narg, char **arg) { - if (narg < 5) error->all("Illegal dump command"); + if (narg < 5) error->all(FLERR,"Illegal dump command"); // error checks for (int idump = 0; idump < ndump; idump++) - if (strcmp(arg[0],dump[idump]->id) == 0) error->all("Reuse of dump ID"); + if (strcmp(arg[0],dump[idump]->id) == 0) error->all(FLERR,"Reuse of dump ID"); int igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find dump group ID"); - if (atoi(arg[3]) <= 0) error->all("Invalid dump frequency"); + if (igroup == -1) error->all(FLERR,"Could not find dump group ID"); + if (atoi(arg[3]) <= 0) error->all(FLERR,"Invalid dump frequency"); // extend Dump list if necessary @@ -398,10 +398,10 @@ void Output::add_dump(int narg, char **arg) #include "style_dump.h" #undef DUMP_CLASS - else error->all("Invalid dump style"); + else error->all(FLERR,"Invalid dump style"); every_dump[ndump] = atoi(arg[3]); - if (every_dump[ndump] <= 0) error->all("Illegal dump command"); + if (every_dump[ndump] <= 0) error->all(FLERR,"Illegal dump command"); last_dump[ndump] = -1; var_dump[ndump] = NULL; ndump++; @@ -413,14 +413,14 @@ void Output::add_dump(int narg, char **arg) void Output::modify_dump(int narg, char **arg) { - if (narg < 1) error->all("Illegal dump_modify command"); + if (narg < 1) error->all(FLERR,"Illegal dump_modify command"); // find which dump it is int idump; for (idump = 0; idump < ndump; idump++) if (strcmp(arg[0],dump[idump]->id) == 0) break; - if (idump == ndump) error->all("Cound not find dump_modify ID"); + if (idump == ndump) error->all(FLERR,"Cound not find dump_modify ID"); dump[idump]->modify_params(narg-1,&arg[1]); } @@ -436,7 +436,7 @@ void Output::delete_dump(char *id) int idump; for (idump = 0; idump < ndump; idump++) if (strcmp(id,dump[idump]->id) == 0) break; - if (idump == ndump) error->all("Could not find undump ID"); + if (idump == ndump) error->all(FLERR,"Could not find undump ID"); delete dump[idump]; delete [] var_dump[idump]; @@ -460,17 +460,17 @@ void Output::delete_dump(char *id) void Output::create_thermo(int narg, char **arg) { - if (narg < 1) error->all("Illegal thermo_style command"); + if (narg < 1) error->all(FLERR,"Illegal thermo_style command"); // don't allow this so that dipole style can safely allocate inertia vector if (domain->box_exist == 0) - error->all("Thermo_style command before simulation box is defined"); + error->all(FLERR,"Thermo_style command before simulation box is defined"); // warn if previous thermo had been modified via thermo_modify command if (thermo->modified && comm->me == 0) - error->warning("New thermo_style command, " + error->warning(FLERR,"New thermo_style command, " "previous thermo_modify settings will be lost"); // set thermo = NULL in case new Thermo throws an error @@ -487,7 +487,7 @@ void Output::create_thermo(int narg, char **arg) void Output::create_restart(int narg, char **arg) { - if (narg < 1) error->all("Illegal restart command"); + if (narg < 1) error->all(FLERR,"Illegal restart command"); if (restart) delete restart; delete [] restart1; @@ -498,7 +498,7 @@ void Output::create_restart(int narg, char **arg) restart_every = atoi(arg[0]); if (restart_every == 0) { - if (narg != 1) error->all("Illegal restart command"); + if (narg != 1) error->all(FLERR,"Illegal restart command"); return; } @@ -517,7 +517,7 @@ void Output::create_restart(int narg, char **arg) n = strlen(arg[2]) + 1; restart2 = new char[n]; strcpy(restart2,arg[2]); - } else error->all("Illegal restart command"); + } else error->all(FLERR,"Illegal restart command"); } /* ---------------------------------------------------------------------- diff --git a/src/pair.cpp b/src/pair.cpp index 0357188ff9..9374ac003b 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -36,9 +36,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; enum{R,RSQ,BMP}; @@ -92,40 +89,40 @@ Pair::~Pair() void Pair::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal pair_modify command"); + if (narg == 0) error->all(FLERR,"Illegal pair_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"mix") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); if (strcmp(arg[iarg+1],"geometric") == 0) mix_flag = GEOMETRIC; else if (strcmp(arg[iarg+1],"arithmetic") == 0) mix_flag = ARITHMETIC; else if (strcmp(arg[iarg+1],"sixthpower") == 0) mix_flag = SIXTHPOWER; - else error->all("Illegal pair_modify command"); + else error->all(FLERR,"Illegal pair_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"shift") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) offset_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) offset_flag = 0; - else error->all("Illegal pair_modify command"); + else error->all(FLERR,"Illegal pair_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"table") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); ncoultablebits = atoi(arg[iarg+1]); if (ncoultablebits > sizeof(float)*CHAR_BIT) - error->all("Too many total bits for bitmapped lookup table"); + error->all(FLERR,"Too many total bits for bitmapped lookup table"); iarg += 2; } else if (strcmp(arg[iarg],"tabinner") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); tabinner = atof(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"tail") == 0) { - if (iarg+2 > narg) error->all("Illegal pair_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) tail_flag = 1; else if (strcmp(arg[iarg+1],"no") == 0) tail_flag = 0; - else error->all("Illegal pair_modify command"); + else error->all(FLERR,"Illegal pair_modify command"); iarg += 2; - } else error->all("Illegal pair_modify command"); + } else error->all(FLERR,"Illegal pair_modify command"); } } @@ -136,19 +133,19 @@ void Pair::init() int i,j; if (offset_flag && tail_flag) - error->all("Cannot have both pair_modify shift and tail set to yes"); + error->all(FLERR,"Cannot have both pair_modify shift and tail set to yes"); if (tail_flag && domain->dimension == 2) - error->all("Cannot use pair tail corrections with 2d simulations"); + error->all(FLERR,"Cannot use pair tail corrections with 2d simulations"); if (tail_flag && domain->nonperiodic && comm->me == 0) - error->warning("Using pair tail corrections with nonperiodic system"); + error->warning(FLERR,"Using pair tail corrections with nonperiodic system"); - if (!allocated) error->all("All pair coeffs are not set"); + if (!allocated) error->all(FLERR,"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"); + if (setflag[i][i] == 0) error->all(FLERR,"All pair coeffs are not set"); // style-specific initialization @@ -959,15 +956,15 @@ void Pair::virial_fdotr_compute() void Pair::write_file(int narg, char **arg) { - if (narg < 8) error->all("Illegal pair_write command"); - if (single_enable == 0) error->all("Pair style does not support pair_write"); + if (narg < 8) error->all(FLERR,"Illegal pair_write command"); + if (single_enable == 0) error->all(FLERR,"Pair style does not support pair_write"); // parse arguments int itype = atoi(arg[0]); int jtype = atoi(arg[1]); if (itype < 1 || itype > atom->ntypes || jtype < 1 || jtype > atom->ntypes) - error->all("Invalid atom types in pair_write command"); + error->all(FLERR,"Invalid atom types in pair_write command"); int n = atoi(arg[2]); @@ -975,12 +972,12 @@ void Pair::write_file(int narg, char **arg) if (strcmp(arg[3],"r") == 0) style = R; else if (strcmp(arg[3],"rsq") == 0) style = RSQ; else if (strcmp(arg[3],"bitmap") == 0) style = BMP; - else error->all("Invalid style in pair_write command"); + else error->all(FLERR,"Invalid style in pair_write command"); double inner = atof(arg[4]); double outer = atof(arg[5]); if (inner <= 0.0 || inner >= outer) - error->all("Invalid cutoffs in pair_write command"); + error->all(FLERR,"Invalid cutoffs in pair_write command"); // open file in append mode // print header in format used by pair_style table @@ -990,7 +987,7 @@ void Pair::write_file(int narg, char **arg) FILE *fp; if (me == 0) { fp = fopen(arg[6],"a"); - if (fp == NULL) error->one("Cannot open pair_write file"); + if (fp == NULL) error->one(FLERR,"Cannot open pair_write file"); fprintf(fp,"# Pair potential %s for atom types %d %d: i,r,energy,force\n", force->pair_style,itype,jtype); if (style == R) @@ -1084,12 +1081,12 @@ void Pair::init_bitmap(double inner, double outer, int ntablebits, int &masklo, int &maskhi, int &nmask, int &nshiftbits) { if (sizeof(int) != sizeof(float)) - error->all("Bitmapped lookup tables require int/float be same size"); + error->all(FLERR,"Bitmapped lookup tables require int/float be same size"); if (ntablebits > sizeof(float)*CHAR_BIT) - error->all("Too many total bits for bitmapped lookup table"); + error->all(FLERR,"Too many total bits for bitmapped lookup table"); - if (inner >= outer) error->warning("Table inner cutoff >= outer cutoff"); + if (inner >= outer) error->warning(FLERR,"Table inner cutoff >= outer cutoff"); int nlowermin = 1; while (!((pow(double(2),nlowermin) <= inner*inner) && @@ -1110,10 +1107,10 @@ void Pair::init_bitmap(double inner, double outer, int ntablebits, int nmantbits = ntablebits - nexpbits; if (nexpbits > sizeof(float)*CHAR_BIT - FLT_MANT_DIG) - error->all("Too many exponent bits for lookup table"); + error->all(FLERR,"Too many exponent bits for lookup table"); if (nmantbits+1 > FLT_MANT_DIG) - error->all("Too many mantissa bits for lookup table"); - if (nmantbits < 3) error->all("Too few bits for lookup table"); + error->all(FLERR,"Too many mantissa bits for lookup table"); + if (nmantbits < 3) error->all(FLERR,"Too few bits for lookup table"); nshiftbits = FLT_MANT_DIG - (nmantbits+1); diff --git a/src/pair_born.cpp b/src/pair_born.cpp index 926a3194e7..406b95a0cc 100644 --- a/src/pair_born.cpp +++ b/src/pair_born.cpp @@ -29,9 +29,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairBorn::PairBorn(LAMMPS *lmp) : Pair(lmp) {} @@ -174,7 +171,7 @@ void PairBorn::allocate() void PairBorn::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = atof(arg[0]); @@ -194,7 +191,7 @@ void PairBorn::settings(int narg, char **arg) void PairBorn::coeff(int narg, char **arg) { - if (narg < 7 || narg > 8) error->all("Incorrect args for pair coefficients"); + if (narg < 7 || narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -204,7 +201,7 @@ void PairBorn::coeff(int narg, char **arg) double a_one = force->numeric(arg[2]); double rho_one = force->numeric(arg[3]); double sigma_one = force->numeric(arg[4]); - if (rho_one <= 0) error->all("Incorrect args for pair coefficients"); + if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients"); double c_one = force->numeric(arg[5]); double d_one = force->numeric(arg[6]); @@ -225,7 +222,7 @@ void PairBorn::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -234,7 +231,7 @@ void PairBorn::coeff(int narg, char **arg) double PairBorn::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); rhoinv[i][j] = 1.0/rho[i][j]; born1[i][j] = a[i][j]/rho[i][j]; diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 02add61142..0490f80eea 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -25,9 +25,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairBuck::PairBuck(LAMMPS *lmp) : Pair(lmp) {} @@ -163,7 +160,7 @@ void PairBuck::allocate() void PairBuck::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -183,7 +180,7 @@ void PairBuck::settings(int narg, char **arg) void PairBuck::coeff(int narg, char **arg) { - if (narg < 5 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -192,7 +189,7 @@ void PairBuck::coeff(int narg, char **arg) double a_one = force->numeric(arg[2]); double rho_one = force->numeric(arg[3]); - if (rho_one <= 0) error->all("Incorrect args for pair coefficients"); + if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients"); double c_one = force->numeric(arg[4]); double cut_one = cut_global; @@ -210,7 +207,7 @@ void PairBuck::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -219,7 +216,7 @@ void PairBuck::coeff(int narg, char **arg) double PairBuck::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); rhoinv[i][j] = 1.0/rho[i][j]; buck1[i][j] = a[i][j]/rho[i][j]; diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index fc405c2da5..66a187ae1a 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -29,9 +29,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairBuckCoulCut::PairBuckCoulCut(LAMMPS *lmp) : Pair(lmp) {} @@ -192,7 +189,7 @@ void PairBuckCoulCut::allocate() void PairBuckCoulCut::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -217,7 +214,7 @@ void PairBuckCoulCut::settings(int narg, char **arg) void PairBuckCoulCut::coeff(int narg, char **arg) { - if (narg < 5 || narg > 7) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 7) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -226,7 +223,7 @@ void PairBuckCoulCut::coeff(int narg, char **arg) double a_one = force->numeric(arg[2]); double rho_one = force->numeric(arg[3]); - if (rho_one <= 0) error->all("Incorrect args for pair coefficients"); + if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients"); double c_one = force->numeric(arg[4]); double cut_lj_one = cut_lj_global; @@ -247,7 +244,7 @@ void PairBuckCoulCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -257,7 +254,7 @@ void PairBuckCoulCut::coeff(int narg, char **arg) void PairBuckCoulCut::init_style() { if (!atom->q_flag) - error->all("Pair style buck/coul/cut requires atom attribute q"); + error->all(FLERR,"Pair style buck/coul/cut requires atom attribute q"); neighbor->request(this); } @@ -268,7 +265,7 @@ void PairBuckCoulCut::init_style() double PairBuckCoulCut::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); double cut = MAX(cut_lj[i][j],cut_coul[i][j]); cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j]; diff --git a/src/pair_coul_cut.cpp b/src/pair_coul_cut.cpp index 16a5224324..fbe2bfdfc2 100644 --- a/src/pair_coul_cut.cpp +++ b/src/pair_coul_cut.cpp @@ -26,9 +26,6 @@ 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) {} @@ -149,7 +146,7 @@ void PairCoulCut::allocate() void PairCoulCut::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -169,7 +166,7 @@ void PairCoulCut::settings(int narg, char **arg) void PairCoulCut::coeff(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all("Incorrect args for pair coefficients"); + if (narg < 2 || narg > 3) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -189,7 +186,7 @@ void PairCoulCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -200,7 +197,7 @@ void PairCoulCut::coeff(int narg, char **arg) void PairCoulCut::init_style() { if (!atom->q_flag) - error->all("Pair style coul/cut requires atom attribute q"); + error->all(FLERR,"Pair style coul/cut requires atom attribute q"); neighbor->request(this); } diff --git a/src/pair_coul_debye.cpp b/src/pair_coul_debye.cpp index 4527919f80..2606a1f3cb 100644 --- a/src/pair_coul_debye.cpp +++ b/src/pair_coul_debye.cpp @@ -26,9 +26,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairCoulDebye::PairCoulDebye(LAMMPS *lmp) : PairCoulCut(lmp) {} @@ -117,7 +114,7 @@ void PairCoulDebye::compute(int eflag, int vflag) void PairCoulDebye::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); kappa = force->numeric(arg[0]); cut_global = force->numeric(arg[1]); diff --git a/src/pair_dpd.cpp b/src/pair_dpd.cpp index 2ffb078bb0..5c701a89e1 100644 --- a/src/pair_dpd.cpp +++ b/src/pair_dpd.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EPSILON 1.0e-10 /* ---------------------------------------------------------------------- */ @@ -188,7 +185,7 @@ void PairDPD::allocate() void PairDPD::settings(int narg, char **arg) { - if (narg != 3) error->all("Illegal pair_style command"); + if (narg != 3) error->all(FLERR,"Illegal pair_style command"); temperature = force->numeric(arg[0]); cut_global = force->numeric(arg[1]); @@ -196,7 +193,7 @@ void PairDPD::settings(int narg, char **arg) // initialize Marsaglia RNG with processor-unique seed - if (seed <= 0) error->all("Illegal pair_style command"); + if (seed <= 0) error->all(FLERR,"Illegal pair_style command"); delete random; random = new RanMars(lmp,seed + comm->me); @@ -216,7 +213,7 @@ void PairDPD::settings(int narg, char **arg) void PairDPD::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -240,7 +237,7 @@ void PairDPD::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -250,12 +247,12 @@ void PairDPD::coeff(int narg, char **arg) void PairDPD::init_style() { if (comm->ghost_velocity == 0) - error->all("Pair dpd requires ghost atoms store velocity"); + error->all(FLERR,"Pair dpd requires ghost atoms store velocity"); // if newton off, forces between atoms ij will be double computed // using different random numbers - if (force->newton_pair == 0 && comm->me == 0) error->warning( + if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, "Pair dpd needs newton pair on for momentum conservation"); neighbor->request(this); @@ -267,7 +264,7 @@ void PairDPD::init_style() double PairDPD::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]); diff --git a/src/pair_dpd_tstat.cpp b/src/pair_dpd_tstat.cpp index cab7a99fab..4151ecc5b1 100644 --- a/src/pair_dpd_tstat.cpp +++ b/src/pair_dpd_tstat.cpp @@ -23,9 +23,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EPSILON 1.0e-10 /* ---------------------------------------------------------------------- */ @@ -141,7 +138,7 @@ void PairDPDTstat::compute(int eflag, int vflag) void PairDPDTstat::settings(int narg, char **arg) { - if (narg != 4) error->all("Illegal pair_style command"); + if (narg != 4) error->all(FLERR,"Illegal pair_style command"); t_start = force->numeric(arg[0]); t_stop = force->numeric(arg[1]); @@ -152,7 +149,7 @@ void PairDPDTstat::settings(int narg, char **arg) // initialize Marsaglia RNG with processor-unique seed - if (seed <= 0) error->all("Illegal pair_style command"); + if (seed <= 0) error->all(FLERR,"Illegal pair_style command"); delete random; random = new RanMars(lmp,seed + comm->me); @@ -172,7 +169,7 @@ void PairDPDTstat::settings(int narg, char **arg) void PairDPDTstat::coeff(int narg, char **arg) { - if (narg < 3 || narg > 4) error->all("Incorrect args for pair coefficients"); + if (narg < 3 || narg > 4) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -196,7 +193,7 @@ void PairDPDTstat::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_gauss.cpp b/src/pair_gauss.cpp index 646a29cdbc..4649cdb0e2 100644 --- a/src/pair_gauss.cpp +++ b/src/pair_gauss.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define EPSILON 1.0e-10 /* ---------------------------------------------------------------------- */ @@ -169,7 +166,7 @@ void PairGauss::allocate() void PairGauss::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = atof(arg[0]); @@ -189,7 +186,7 @@ void PairGauss::settings(int narg, char **arg) void PairGauss::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo, ihi, jlo, jhi; @@ -213,7 +210,7 @@ void PairGauss::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -222,7 +219,7 @@ void PairGauss::coeff(int narg, char **arg) double PairGauss::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); if (offset_flag) offset[i][j] = a[i][j]*exp(-b[i][j]*cut[i][j]*cut[i][j]); else offset[i][j] = 0.0; diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index a57bf33721..97939fef30 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp) @@ -177,7 +174,7 @@ void PairHybrid::settings(int narg, char **arg) { int i,m,istyle; - if (narg < 1) error->all("Illegal pair_style command"); + if (narg < 1) error->all(FLERR,"Illegal pair_style command"); // delete old lists, since cannot just change settings @@ -236,11 +233,11 @@ void PairHybrid::settings(int narg, char **arg) 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"); + error->all(FLERR,"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"); + error->all(FLERR,"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"); + error->all(FLERR,"Pair style hybrid cannot have none as an argument"); styles[nstyles] = force->new_pair(arg[i],NULL,dummy); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); @@ -283,7 +280,7 @@ void PairHybrid::settings(int narg, char **arg) void PairHybrid::coeff(int narg, char **arg) { - if (narg < 3) error->all("Incorrect args for pair coefficients"); + if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -300,7 +297,7 @@ void PairHybrid::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[2],"none") == 0) none = 1; - else error->all("Pair coeff for hybrid has invalid style"); + else error->all(FLERR,"Pair coeff for hybrid has invalid style"); } // move 1st/2nd args to 2nd/3rd args @@ -346,7 +343,7 @@ void PairHybrid::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -367,7 +364,7 @@ void PairHybrid::init_style() 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"); + if (used == 0) error->all(FLERR,"Pair hybrid sub-style is not used"); } // each sub-style makes its neighbor list request(s) @@ -455,7 +452,7 @@ double PairHybrid::init_one(int i, int j) 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"); + error->one(FLERR,"All pair coeffs are not set"); nmap[i][j] = 1; map[i][j][0] = map[i][i][0]; } @@ -601,7 +598,7 @@ double PairHybrid::single(int i, int j, int itype, int jtype, double &fforce) { if (nmap[itype][jtype] == 0) - error->one("Invoked pair single on pair style none"); + error->one(FLERR,"Invoked pair single on pair style none"); double fone; fforce = 0.0; @@ -610,7 +607,7 @@ double PairHybrid::single(int i, int j, int itype, int jtype, for (int m = 0; m < nmap[itype][jtype]; m++) { if (rsq < styles[map[itype][jtype][m]]->cutsq[itype][jtype]) { if (styles[map[itype][jtype][m]]->single_enable == 0) - error->all("Pair hybrid sub-style does not support single call"); + error->all(FLERR,"Pair hybrid sub-style does not support single call"); esum += styles[map[itype][jtype][m]]-> single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone); fforce += fone; @@ -663,7 +660,7 @@ void *PairHybrid::extract(char *str, int &dim) double *p_newvalue = (double *) ptr; double newvalue = *p_newvalue; if (cutptr && newvalue != cutvalue) - error->all("Coulomb cutoffs of pair hybrid sub-styles do not match"); + error->all(FLERR,"Coulomb cutoffs of pair hybrid sub-styles do not match"); cutptr = ptr; cutvalue = newvalue; } else if (ptr) return ptr; diff --git a/src/pair_hybrid_overlay.cpp b/src/pair_hybrid_overlay.cpp index f6b73bffb3..4d3e14af3d 100644 --- a/src/pair_hybrid_overlay.cpp +++ b/src/pair_hybrid_overlay.cpp @@ -21,9 +21,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairHybridOverlay::PairHybridOverlay(LAMMPS *lmp) : PairHybrid(lmp) {} @@ -34,7 +31,7 @@ PairHybridOverlay::PairHybridOverlay(LAMMPS *lmp) : PairHybrid(lmp) {} void PairHybridOverlay::coeff(int narg, char **arg) { - if (narg < 3) error->all("Incorrect args for pair coefficients"); + if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -51,7 +48,7 @@ void PairHybridOverlay::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[2],"none") == 0) none = 1; - else error->all("Pair coeff for hybrid has invalid style"); + else error->all(FLERR,"Pair coeff for hybrid has invalid style"); } // move 1st/2nd args to 2nd/3rd args @@ -88,7 +85,7 @@ void PairHybridOverlay::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_lj96_cut.cpp b/src/pair_lj96_cut.cpp index 758ef0ab58..76f808dd03 100644 --- a/src/pair_lj96_cut.cpp +++ b/src/pair_lj96_cut.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJ96Cut::PairLJ96Cut(LAMMPS *lmp) : Pair(lmp) @@ -433,7 +430,7 @@ void PairLJ96Cut::allocate() void PairLJ96Cut::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -453,7 +450,7 @@ void PairLJ96Cut::settings(int narg, char **arg) void PairLJ96Cut::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -477,7 +474,7 @@ void PairLJ96Cut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -575,7 +572,7 @@ double PairLJ96Cut::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && cut[i][j] < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); // compute I,J contribution to long-range tail correction // count total # of atoms of type I and J via Allreduce diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp index 545e0ab29b..df06f7deda 100644 --- a/src/pair_lj_cubic.cpp +++ b/src/pair_lj_cubic.cpp @@ -32,9 +32,6 @@ using namespace LAMMPS_NS; using namespace PairLJCubicConstants; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCubic::PairLJCubic(LAMMPS *lmp) : Pair(lmp) {} @@ -180,7 +177,7 @@ void PairLJCubic::allocate() void PairLJCubic::settings(int narg, char **arg) { - if (narg != 0) error->all("Illegal pair_style command"); + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); // reset cutoffs that have been explicitly set @@ -199,7 +196,7 @@ void PairLJCubic::settings(int narg, char **arg) void PairLJCubic::coeff(int narg, char **arg) { if (narg != 4) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -222,7 +219,7 @@ void PairLJCubic::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp index 5af7e1c89b..671d6420cf 100644 --- a/src/pair_lj_cut.cpp +++ b/src/pair_lj_cut.cpp @@ -34,9 +34,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCut::PairLJCut(LAMMPS *lmp) : Pair(lmp) @@ -427,7 +424,7 @@ void PairLJCut::allocate() void PairLJCut::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -447,7 +444,7 @@ void PairLJCut::settings(int narg, char **arg) void PairLJCut::coeff(int narg, char **arg) { - if (narg < 4 || narg > 5) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -471,7 +468,7 @@ void PairLJCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -569,7 +566,7 @@ double PairLJCut::init_one(int i, int j) // check interior rRESPA cutoff if (cut_respa && cut[i][j] < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); + error->all(FLERR,"Pair cutoff < Respa interior cutoff"); // compute I,J contribution to long-range tail correction // count total # of atoms of type I and J via Allreduce diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp index efd0344823..1d311d4b72 100644 --- a/src/pair_lj_cut_coul_cut.cpp +++ b/src/pair_lj_cut_coul_cut.cpp @@ -26,9 +26,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJCutCoulCut::PairLJCutCoulCut(LAMMPS *lmp) : Pair(lmp) {} @@ -185,7 +182,7 @@ void PairLJCutCoulCut::allocate() void PairLJCutCoulCut::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); + if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = force->numeric(arg[0]); if (narg == 1) cut_coul_global = cut_lj_global; @@ -210,7 +207,7 @@ void PairLJCutCoulCut::settings(int narg, char **arg) void PairLJCutCoulCut::coeff(int narg, char **arg) { - if (narg < 4 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 4 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -237,7 +234,7 @@ void PairLJCutCoulCut::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -247,7 +244,7 @@ void PairLJCutCoulCut::coeff(int narg, char **arg) void PairLJCutCoulCut::init_style() { if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut requires atom attribute q"); + error->all(FLERR,"Pair style lj/cut/coul/cut requires atom attribute q"); neighbor->request(this); } diff --git a/src/pair_lj_cut_coul_debye.cpp b/src/pair_lj_cut_coul_debye.cpp index 1954d0d1f2..023d866542 100644 --- a/src/pair_lj_cut_coul_debye.cpp +++ b/src/pair_lj_cut_coul_debye.cpp @@ -131,7 +131,7 @@ void PairLJCutCoulDebye::compute(int eflag, int vflag) void PairLJCutCoulDebye::settings(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all("Illegal pair_style command"); + if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command"); kappa = force->numeric(arg[0]); cut_lj_global = force->numeric(arg[1]); diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 1f5e659da7..57110ac81c 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJExpand::PairLJExpand(LAMMPS *lmp) : Pair(lmp) {} @@ -165,7 +162,7 @@ void PairLJExpand::allocate() void PairLJExpand::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -185,7 +182,7 @@ void PairLJExpand::settings(int narg, char **arg) void PairLJExpand::coeff(int narg, char **arg) { - if (narg < 5 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -211,7 +208,7 @@ void PairLJExpand::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_lj_gromacs.cpp b/src/pair_lj_gromacs.cpp index 462c1f2f23..5b43ff2acc 100644 --- a/src/pair_lj_gromacs.cpp +++ b/src/pair_lj_gromacs.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJGromacs::PairLJGromacs(LAMMPS *lmp) : Pair(lmp) {} @@ -189,13 +186,13 @@ void PairLJGromacs::allocate() void PairLJGromacs::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); cut_inner_global = force->numeric(arg[0]); cut_global = force->numeric(arg[1]); if (cut_inner_global <= 0.0 || cut_inner_global > cut_global) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); // reset cutoffs that have been explicitly set @@ -217,7 +214,7 @@ void PairLJGromacs::settings(int narg, char **arg) void PairLJGromacs::coeff(int narg, char **arg) { if (narg != 4 && narg != 6) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -235,7 +232,7 @@ void PairLJGromacs::coeff(int narg, char **arg) } if (cut_inner_one <= 0.0 || cut_inner_one > cut_one) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -249,7 +246,7 @@ void PairLJGromacs::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_lj_gromacs_coul_gromacs.cpp b/src/pair_lj_gromacs_coul_gromacs.cpp index e60cf82291..af681aeab0 100644 --- a/src/pair_lj_gromacs_coul_gromacs.cpp +++ b/src/pair_lj_gromacs_coul_gromacs.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJGromacsCoulGromacs::PairLJGromacsCoulGromacs(LAMMPS *lmp) : Pair(lmp) {} @@ -217,7 +214,7 @@ void PairLJGromacsCoulGromacs::allocate() void PairLJGromacsCoulGromacs::settings(int narg, char **arg) { if (narg != 2 && narg != 4) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); cut_lj_inner = force->numeric(arg[0]); cut_lj = force->numeric(arg[1]); @@ -230,9 +227,9 @@ void PairLJGromacsCoulGromacs::settings(int narg, char **arg) } if (cut_lj_inner <= 0.0 || cut_coul_inner < 0.0) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); if (cut_lj_inner > cut_lj || cut_coul_inner > cut_coul) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -241,7 +238,7 @@ void PairLJGromacsCoulGromacs::settings(int narg, char **arg) void PairLJGromacsCoulGromacs::coeff(int narg, char **arg) { - if (narg != 4) error->all("Incorrect args for pair coefficients"); + if (narg != 4) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -261,7 +258,7 @@ void PairLJGromacsCoulGromacs::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -271,7 +268,7 @@ void PairLJGromacsCoulGromacs::coeff(int narg, char **arg) void PairLJGromacsCoulGromacs::init_style() { if (!atom->q_flag) - error->all("Pair style lj/gromacs/coul/gromacs requires atom attribute q"); + error->all(FLERR,"Pair style lj/gromacs/coul/gromacs requires atom attribute q"); neighbor->request(this); diff --git a/src/pair_lj_smooth.cpp b/src/pair_lj_smooth.cpp index af85406dab..de1276991c 100644 --- a/src/pair_lj_smooth.cpp +++ b/src/pair_lj_smooth.cpp @@ -28,9 +28,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairLJSmooth::PairLJSmooth(LAMMPS *lmp) : Pair(lmp) {} @@ -193,13 +190,13 @@ void PairLJSmooth::allocate() void PairLJSmooth::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); cut_inner_global = force->numeric(arg[0]); cut_global = force->numeric(arg[1]); if (cut_inner_global <= 0.0 || cut_inner_global > cut_global) - error->all("Illegal pair_style command"); + error->all(FLERR,"Illegal pair_style command"); // reset cutoffs that have been explicitly set @@ -221,7 +218,7 @@ void PairLJSmooth::settings(int narg, char **arg) void PairLJSmooth::coeff(int narg, char **arg) { if (narg != 4 && narg != 6) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -239,7 +236,7 @@ void PairLJSmooth::coeff(int narg, char **arg) } if (cut_inner_one <= 0.0 || cut_inner_one > cut_one) - error->all("Incorrect args for pair coefficients"); + error->all(FLERR,"Incorrect args for pair coefficients"); int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -253,7 +250,7 @@ void PairLJSmooth::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_morse.cpp b/src/pair_morse.cpp index 0817fd3fb5..d05235a978 100644 --- a/src/pair_morse.cpp +++ b/src/pair_morse.cpp @@ -24,9 +24,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairMorse::PairMorse(LAMMPS *lmp) : Pair(lmp) {} @@ -155,7 +152,7 @@ void PairMorse::allocate() void PairMorse::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -175,7 +172,7 @@ void PairMorse::settings(int narg, char **arg) void PairMorse::coeff(int narg, char **arg) { - if (narg < 5 || narg > 6) error->all("Incorrect args for pair coefficients"); + if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -201,7 +198,7 @@ void PairMorse::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -211,7 +208,7 @@ void PairMorse::coeff(int narg, char **arg) double PairMorse::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); morse1[i][j] = 2.0*d0[i][j]*alpha[i][j]; diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index 758a3f041a..ce25f4a782 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -26,9 +26,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) @@ -150,7 +147,7 @@ void PairSoft::allocate() void PairSoft::settings(int narg, char **arg) { - if (narg != 1) error->all("Illegal pair_style command"); + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(arg[0]); @@ -170,7 +167,7 @@ void PairSoft::settings(int narg, char **arg) void PairSoft::coeff(int narg, char **arg) { - if (narg < 3 || narg > 4) error->all("Incorrect args for pair coefficients"); + if (narg < 3 || narg > 4) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -192,7 +189,7 @@ void PairSoft::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pair_table.cpp b/src/pair_table.cpp index 64e737933d..40530b1638 100644 --- a/src/pair_table.cpp +++ b/src/pair_table.cpp @@ -29,9 +29,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define LOOKUP 0 #define LINEAR 1 #define SPLINE 2 @@ -119,24 +116,24 @@ void PairTable::compute(int eflag, int vflag) if (rsq < cutsq[itype][jtype]) { tb = &tables[tabindex[itype][jtype]]; if (rsq < tb->innersq) - error->one("Pair distance < table inner cutoff"); + error->one(FLERR,"Pair distance < table inner cutoff"); if (tabstyle == LOOKUP) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) - error->one("Pair distance > table outer cutoff"); + error->one(FLERR,"Pair distance > table outer cutoff"); fpair = factor_lj * tb->f[itable]; } else if (tabstyle == LINEAR) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) - error->one("Pair distance > table outer cutoff"); + error->one(FLERR,"Pair distance > table outer cutoff"); fraction = (rsq - tb->rsq[itable]) * tb->invdelta; value = tb->f[itable] + fraction*tb->df[itable]; fpair = factor_lj * value; } else if (tabstyle == SPLINE) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) - error->one("Pair distance > table outer cutoff"); + error->one(FLERR,"Pair distance > table outer cutoff"); b = (rsq - tb->rsq[itable]) * tb->invdelta; a = 1.0 - b; value = a * tb->f[itable] + b * tb->f[itable+1] + @@ -206,7 +203,7 @@ void PairTable::allocate() void PairTable::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); // new settings @@ -214,10 +211,10 @@ void PairTable::settings(int narg, char **arg) else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE; else if (strcmp(arg[0],"bitmap") == 0) tabstyle = BITMAP; - else error->all("Unknown table style in pair_style command"); + else error->all(FLERR,"Unknown table style in pair_style command"); tablength = force->inumeric(arg[1]); - if (tablength < 2) error->all("Illegal number of pair table entries"); + if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); // delete old tables, since cannot just change settings @@ -241,7 +238,7 @@ void PairTable::settings(int narg, char **arg) void PairTable::coeff(int narg, char **arg) { - if (narg != 4 && narg != 5) error->all("Illegal pair_coeff command"); + if (narg != 4 && narg != 5) error->all(FLERR,"Illegal pair_coeff command"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -267,7 +264,7 @@ void PairTable::coeff(int narg, char **arg) // insure cutoff is within table // for BITMAP tables, file values can be in non-ascending order - if (tb->ninput <= 1) error->one("Invalid pair table length"); + if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); double rlo,rhi; if (tb->rflag == 0) { rlo = tb->rfile[0]; @@ -276,8 +273,8 @@ void PairTable::coeff(int narg, char **arg) rlo = tb->rlo; rhi = tb->rhi; } - if (tb->cut <= rlo || tb->cut > rhi) error->all("Invalid pair table cutoff"); - if (rlo <= 0.0) error->all("Invalid pair table cutoff"); + if (tb->cut <= rlo || tb->cut > rhi) error->all(FLERR,"Invalid pair table cutoff"); + if (rlo <= 0.0) error->all(FLERR,"Invalid pair table cutoff"); // match = 1 if don't need to spline read-in tables // this is only the case if r values needed by final tables @@ -290,7 +287,7 @@ void PairTable::coeff(int narg, char **arg) if (tabstyle == BITMAP && tb->ninput == 1 << tablength && tb->rflag == BMP && tb->rhi == tb->cut) tb->match = 1; if (tb->rflag == BMP && tb->match == 0) - error->all("Bitmapped table in file does not match requested table"); + error->all(FLERR,"Bitmapped table in file does not match requested table"); // spline read-in values and compute r,e,f vectors within table @@ -308,7 +305,7 @@ void PairTable::coeff(int narg, char **arg) } } - if (count == 0) error->all("Illegal pair_coeff command"); + if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); ntables++; } @@ -318,7 +315,7 @@ void PairTable::coeff(int narg, char **arg) double PairTable::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); tabindex[j][i] = tabindex[i][j]; @@ -342,14 +339,14 @@ void PairTable::read_table(Table *tb, char *file, char *keyword) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) - error->one("Did not find keyword in table file"); + error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment if (strstr(line,keyword) == line) break; // matching keyword @@ -375,7 +372,7 @@ void PairTable::read_table(Table *tb, char *file, char *keyword) if (tb->rflag == BMP) { while (1 << tb->ntablebits < tb->ninput) tb->ntablebits++; if (1 << tb->ntablebits != tb->ninput) - error->one("Bitmapped table is incorrect length in table file"); + error->one(FLERR,"Bitmapped table is incorrect length in table file"); init_bitmap(tb->rlo,tb->rhi,tb->ntablebits,masklo,maskhi,nmask,nshiftbits); } @@ -509,12 +506,12 @@ void PairTable::param_extract(Table *tb, char *line) tb->fphi = atof(word); } else { printf("WORD: %s\n",word); - error->one("Invalid keyword in pair table parameters"); + error->one(FLERR,"Invalid keyword in pair table parameters"); } word = strtok(NULL," \t\n\r\f"); } - if (tb->ninput == 0) error->one("Pair table parameters did not set N"); + if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); } /* ---------------------------------------------------------------------- @@ -901,21 +898,21 @@ double PairTable::single(int i, int j, int itype, int jtype, double rsq, int tlm1 = tablength - 1; Table *tb = &tables[tabindex[itype][jtype]]; - if (rsq < tb->innersq) error->one("Pair distance < table inner cutoff"); + if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); if (tabstyle == LOOKUP) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one("Pair distance > table outer cutoff"); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fforce = factor_lj * tb->f[itable]; } else if (tabstyle == LINEAR) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one("Pair distance > table outer cutoff"); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fraction = (rsq - tb->rsq[itable]) * tb->invdelta; value = tb->f[itable] + fraction*tb->df[itable]; fforce = factor_lj * value; } else if (tabstyle == SPLINE) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one("Pair distance > table outer cutoff"); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); b = (rsq - tb->rsq[itable]) * tb->invdelta; a = 1.0 - b; value = a * tb->f[itable] + b * tb->f[itable+1] + @@ -952,12 +949,12 @@ double PairTable::single(int i, int j, int itype, int jtype, double rsq, void *PairTable::extract(char *str, int &dim) { if (strcmp(str,"cut_coul") != 0) return NULL; - if (ntables == 0) error->all("All pair coeffs are not set"); + if (ntables == 0) error->all(FLERR,"All pair coeffs are not set"); double cut_coul = tables[0].cut; for (int m = 1; m < ntables; m++) if (tables[m].cut != cut_coul) - error->all("Pair table cutoffs must all be equal to use with KSpace"); + error->all(FLERR,"Pair table cutoffs must all be equal to use with KSpace"); dim = 0; return &tables[0].cut; } diff --git a/src/pair_yukawa.cpp b/src/pair_yukawa.cpp index 85359921db..0e544c116e 100644 --- a/src/pair_yukawa.cpp +++ b/src/pair_yukawa.cpp @@ -23,9 +23,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ PairYukawa::PairYukawa(LAMMPS *lmp) : Pair(lmp) {} @@ -152,7 +149,7 @@ void PairYukawa::allocate() void PairYukawa::settings(int narg, char **arg) { - if (narg != 2) error->all("Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); kappa = force->numeric(arg[0]); cut_global = force->numeric(arg[1]); @@ -173,7 +170,7 @@ void PairYukawa::settings(int narg, char **arg) void PairYukawa::coeff(int narg, char **arg) { - if (narg < 3 || narg > 4) error->all("Incorrect args for pair coefficients"); + if (narg < 3 || narg > 4) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -195,7 +192,7 @@ void PairYukawa::coeff(int narg, char **arg) } } - if (count == 0) error->all("Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- diff --git a/src/pointers.h b/src/pointers.h index f2f2215b8b..d00665c973 100644 --- a/src/pointers.h +++ b/src/pointers.h @@ -27,6 +27,13 @@ namespace LAMMPS_NS { +// universal defines inside namespace + +#define FLERR __FILE__,__LINE__ + +#define MIN(A,B) ((A) < (B)) ? (A) : (B) +#define MAX(A,B) ((A) > (B)) ? (A) : (B) + class Pointers { public: Pointers(LAMMPS *ptr) : diff --git a/src/random_mars.cpp b/src/random_mars.cpp index 966f3a6717..2430eabd56 100644 --- a/src/random_mars.cpp +++ b/src/random_mars.cpp @@ -27,7 +27,7 @@ RanMars::RanMars(LAMMPS *lmp, int seed) : Pointers(lmp) double s,t; if (seed <= 0 || seed > 900000000) - error->all("Invalid seed for Marsaglia random # generator"); + error->all(FLERR,"Invalid seed for Marsaglia random # generator"); save = 0; u = new double[97+1]; diff --git a/src/random_park.cpp b/src/random_park.cpp index cbfa0d109e..456020ff25 100644 --- a/src/random_park.cpp +++ b/src/random_park.cpp @@ -40,7 +40,7 @@ using namespace LAMMPS_NS; RanPark::RanPark(LAMMPS *lmp, int seed_init) : Pointers(lmp) { - if (seed_init <= 0) error->all("Invalid seed for Park random # generator"); + if (seed_init <= 0) error->all(FLERR,"Invalid seed for Park random # generator"); seed = seed_init; save = 0; } @@ -89,7 +89,7 @@ double RanPark::gaussian() void RanPark::reset(int seed_init) { - if (seed_init <= 0) error->all("Invalid seed for Park random # generator"); + if (seed_init <= 0) error->all(FLERR,"Invalid seed for Park random # generator"); seed = seed_init; save = 0; } diff --git a/src/read_data.cpp b/src/read_data.cpp index e7b14b84d8..a5a5e47ccb 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -44,9 +44,6 @@ using namespace LAMMPS_NS; // customize for new sections #define NSECTIONS 21 // change when add to header::section_keywords -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp) @@ -79,12 +76,12 @@ ReadData::~ReadData() void ReadData::command(int narg, char **arg) { - if (narg != 1) error->all("Illegal read_data command"); + if (narg != 1) error->all(FLERR,"Illegal read_data command"); if (domain->box_exist) - error->all("Cannot read_data after simulation box is defined"); + error->all(FLERR,"Cannot read_data after simulation box is defined"); if (domain->dimension == 2 && domain->zperiodic == 0) - error->all("Cannot run 2d simulation with nonperiodic Z dimension"); + error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension"); // scan data file to determine max topology needed per atom // allocate initial topology arrays @@ -147,122 +144,122 @@ void ReadData::command(int narg, char **arg) atoms(); atomflag = 1; } else if (strcmp(keyword,"Velocities") == 0) { - if (atomflag == 0) error->all("Must read Atoms before Velocities"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Velocities"); velocities(); } else if (strcmp(keyword,"Ellipsoids") == 0) { if (!avec_ellipsoid) - error->all("Invalid data file section: Ellipsoids"); - if (atomflag == 0) error->all("Must read Atoms before Ellipsoids"); + error->all(FLERR,"Invalid data file section: Ellipsoids"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids"); ellipsoids(); } else if (strcmp(keyword,"Bonds") == 0) { if (atom->avec->bonds_allow == 0) - error->all("Invalid data file section: Bonds"); - if (atomflag == 0) error->all("Must read Atoms before Bonds"); + error->all(FLERR,"Invalid data file section: Bonds"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds"); bonds(); } else if (strcmp(keyword,"Angles") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: Angles"); - if (atomflag == 0) error->all("Must read Atoms before Angles"); + error->all(FLERR,"Invalid data file section: Angles"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles"); angles(); } else if (strcmp(keyword,"Dihedrals") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: Dihedrals"); - if (atomflag == 0) error->all("Must read Atoms before Dihedrals"); + error->all(FLERR,"Invalid data file section: Dihedrals"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals"); dihedrals(); } else if (strcmp(keyword,"Impropers") == 0) { if (atom->avec->impropers_allow == 0) - error->all("Invalid data file section: Impropers"); - if (atomflag == 0) error->all("Must read Atoms before Impropers"); + error->all(FLERR,"Invalid data file section: Impropers"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers"); impropers(); } else if (strcmp(keyword,"Masses") == 0) { mass(); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) - error->all("Must define pair_style before Pair Coeffs"); + error->all(FLERR,"Must define pair_style before Pair Coeffs"); paircoeffs(); } else if (strcmp(keyword,"Bond Coeffs") == 0) { if (atom->avec->bonds_allow == 0) - error->all("Invalid data file section: Bond Coeffs"); + error->all(FLERR,"Invalid data file section: Bond Coeffs"); if (force->bond == NULL) - error->all("Must define bond_style before Bond Coeffs"); + error->all(FLERR,"Must define bond_style before Bond Coeffs"); bondcoeffs(); } else if (strcmp(keyword,"Angle Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: Angle Coeffs"); + error->all(FLERR,"Invalid data file section: Angle Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before Angle Coeffs"); + error->all(FLERR,"Must define angle_style before Angle Coeffs"); anglecoeffs(0); } else if (strcmp(keyword,"Dihedral Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: Dihedral Coeffs"); + error->all(FLERR,"Invalid data file section: Dihedral Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before Dihedral Coeffs"); + error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs"); dihedralcoeffs(0); } else if (strcmp(keyword,"Improper Coeffs") == 0) { if (atom->avec->impropers_allow == 0) - error->all("Invalid data file section: Improper Coeffs"); + error->all(FLERR,"Invalid data file section: Improper Coeffs"); if (force->improper == NULL) - error->all("Must define improper_style before Improper Coeffs"); + error->all(FLERR,"Must define improper_style before Improper Coeffs"); impropercoeffs(0); } else if (strcmp(keyword,"BondBond Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: BondBond Coeffs"); + error->all(FLERR,"Invalid data file section: BondBond Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before BondBond Coeffs"); + error->all(FLERR,"Must define angle_style before BondBond Coeffs"); anglecoeffs(1); } else if (strcmp(keyword,"BondAngle Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: BondAngle Coeffs"); + error->all(FLERR,"Invalid data file section: BondAngle Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before BondAngle Coeffs"); + error->all(FLERR,"Must define angle_style before BondAngle Coeffs"); anglecoeffs(2); } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: MiddleBondTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); dihedralcoeffs(1); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: EndBondTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before EndBondTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); dihedralcoeffs(2); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: AngleTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before AngleTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); dihedralcoeffs(3); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: AngleAngleTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); dihedralcoeffs(4); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: BondBond13 Coeffs"); + error->all(FLERR,"Invalid data file section: BondBond13 Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before BondBond13 Coeffs"); + error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs"); dihedralcoeffs(5); } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) { if (atom->avec->impropers_allow == 0) - error->all("Invalid data file section: AngleAngle Coeffs"); + error->all(FLERR,"Invalid data file section: AngleAngle Coeffs"); if (force->improper == NULL) - error->all("Must define improper_style before AngleAngle Coeffs"); + error->all(FLERR,"Must define improper_style before AngleAngle Coeffs"); impropercoeffs(1); } else { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); - error->all(str); + error->all(FLERR,str); } parse_keyword(0,1); @@ -277,7 +274,7 @@ void ReadData::command(int narg, char **arg) // error if natoms > 0 yet no atoms were read - if (atom->natoms > 0 && atomflag == 0) error->all("No atoms in data file"); + if (atom->natoms > 0 && atomflag == 0) error->all(FLERR,"No atoms in data file"); // create bond topology now that system is defined @@ -318,7 +315,7 @@ void ReadData::header(int flag) if (me == 0) { char *eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); } // customize for new header lines @@ -374,7 +371,7 @@ void ReadData::header(int flag) else if (strstr(line,"ellipsoids")) { if (!avec_ellipsoid) - error->all("No ellipsoids allowed with this atom style"); + error->all(FLERR,"No ellipsoids allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nellipsoids); } @@ -397,8 +394,8 @@ void ReadData::header(int flag) atom->nangles < 0 || atom->nangles > MAXBIGINT || atom->ndihedrals < 0 || atom->ndihedrals > MAXBIGINT || atom->nimpropers < 0 || atom->nimpropers > MAXBIGINT) { - if (flag == 0) error->one("System in data file is too big"); - else error->all("System in data file is too big"); + if (flag == 0) error->one(FLERR,"System in data file is too big"); + else error->all(FLERR,"System in data file is too big"); } // check that exiting string is a valid section keyword @@ -409,32 +406,32 @@ void ReadData::header(int flag) if (n == NSECTIONS) { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); - error->all(str); + error->all(FLERR,str); } // error check on consistency of header values if ((atom->nbonds || atom->nbondtypes) && atom->avec->bonds_allow == 0) - error->one("No bonds allowed with this atom style"); + error->one(FLERR,"No bonds allowed with this atom style"); if ((atom->nangles || atom->nangletypes) && atom->avec->angles_allow == 0) - error->one("No angles allowed with this atom style"); + error->one(FLERR,"No angles allowed with this atom style"); if ((atom->ndihedrals || atom->ndihedraltypes) && atom->avec->dihedrals_allow == 0) - error->one("No dihedrals allowed with this atom style"); + error->one(FLERR,"No dihedrals allowed with this atom style"); if ((atom->nimpropers || atom->nimpropertypes) && atom->avec->impropers_allow == 0) - error->one("No impropers allowed with this atom style"); + error->one(FLERR,"No impropers allowed with this atom style"); if (atom->nbonds > 0 && atom->nbondtypes <= 0) - error->one("Bonds defined but no bond types"); + error->one(FLERR,"Bonds defined but no bond types"); if (atom->nangles > 0 && atom->nangletypes <= 0) - error->one("Angles defined but no angle types"); + error->one(FLERR,"Angles defined but no angle types"); if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0) - error->one("Dihedrals defined but no dihedral types"); + error->one(FLERR,"Dihedrals defined but no dihedral types"); if (atom->nimpropers > 0 && atom->nimpropertypes <= 0) - error->one("Impropers defined but no improper types"); + error->one(FLERR,"Impropers defined but no improper types"); } /* ---------------------------------------------------------------------- @@ -456,7 +453,7 @@ void ReadData::atoms() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -478,7 +475,7 @@ void ReadData::atoms() if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } - if (natoms != atom->natoms) error->all("Did not assign all atoms correctly"); + if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); // if any atom ID < 0, error // if all atom IDs = 0, tag_enable = 0 @@ -494,7 +491,7 @@ void ReadData::atoms() int flag_all; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) - error->all("Invalid atom ID in Atoms section of data file"); + error->all(FLERR,"Invalid atom ID in Atoms section of data file"); flag = 0; for (int i = 0; i < nlocal; i++) @@ -508,7 +505,7 @@ void ReadData::atoms() if (tag[i] == 0) flag = 1; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) - error->all("Invalid atom ID in Atoms section of data file"); + error->all(FLERR,"Invalid atom ID in Atoms section of data file"); } // create global mapping @@ -547,7 +544,7 @@ void ReadData::velocities() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -598,7 +595,7 @@ void ReadData::ellipsoids() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -637,7 +634,7 @@ void ReadData::bonds() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -663,7 +660,7 @@ void ReadData::bonds() if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor); } - if (sum != factor*atom->nbonds) error->all("Bonds assigned incorrectly"); + if (sum != factor*atom->nbonds) error->all(FLERR,"Bonds assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -682,7 +679,7 @@ void ReadData::angles() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -708,7 +705,7 @@ void ReadData::angles() if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor); } - if (sum != factor*atom->nangles) error->all("Angles assigned incorrectly"); + if (sum != factor*atom->nangles) error->all(FLERR,"Angles assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -727,7 +724,7 @@ void ReadData::dihedrals() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -754,7 +751,7 @@ void ReadData::dihedrals() if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",sum/factor); } if (sum != factor*atom->ndihedrals) - error->all("Dihedrals assigned incorrectly"); + error->all(FLERR,"Dihedrals assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -773,7 +770,7 @@ void ReadData::impropers() m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; @@ -800,7 +797,7 @@ void ReadData::impropers() if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",sum/factor); } if (sum != factor*atom->nimpropers) - error->all("Impropers assigned incorrectly"); + error->all(FLERR,"Impropers assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -816,7 +813,7 @@ void ReadData::mass() m = 0; for (i = 0; i < atom->ntypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -845,7 +842,7 @@ void ReadData::paircoeffs() m = 0; for (i = 0; i < atom->ntypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -876,7 +873,7 @@ void ReadData::bondcoeffs() m = 0; for (i = 0; i < atom->nbondtypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -907,7 +904,7 @@ void ReadData::anglecoeffs(int which) m = 0; for (i = 0; i < atom->nangletypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -940,7 +937,7 @@ void ReadData::dihedralcoeffs(int which) m = 0; for (i = 0; i < atom->ndihedraltypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -976,7 +973,7 @@ void ReadData::impropercoeffs(int which) m = 0; for (i = 0; i < atom->nimpropertypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } @@ -1006,7 +1003,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, char *eof; if (atom->natoms > MAXSMALLINT) - error->all("Molecular data file has too many atoms"); + error->all(FLERR,"Molecular data file has too many atoms"); // customize for new sections @@ -1031,86 +1028,86 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, else if (strcmp(keyword,"Ellipsoids") == 0) { if (!avec_ellipsoid) - error->all("Invalid data file section: Ellipsoids"); + error->all(FLERR,"Invalid data file section: Ellipsoids"); ellipsoid_flag = 1; skip_lines(nellipsoids); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) - error->all("Must define pair_style before Pair Coeffs"); + error->all(FLERR,"Must define pair_style before Pair Coeffs"); skip_lines(atom->ntypes); } else if (strcmp(keyword,"Bond Coeffs") == 0) { if (atom->avec->bonds_allow == 0) - error->all("Invalid data file section: Bond Coeffs"); + error->all(FLERR,"Invalid data file section: Bond Coeffs"); if (force->bond == NULL) - error->all("Must define bond_style before Bond Coeffs"); + error->all(FLERR,"Must define bond_style before Bond Coeffs"); skip_lines(atom->nbondtypes); } else if (strcmp(keyword,"Angle Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: Angle Coeffs"); + error->all(FLERR,"Invalid data file section: Angle Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before Angle Coeffs"); + error->all(FLERR,"Must define angle_style before Angle Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"Dihedral Coeffs") == 0) { skip_lines(atom->ndihedraltypes); if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: Dihedral Coeffs"); + error->all(FLERR,"Invalid data file section: Dihedral Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before Dihedral Coeffs"); + error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs"); } else if (strcmp(keyword,"Improper Coeffs") == 0) { if (atom->avec->impropers_allow == 0) - error->all("Invalid data file section: Improper Coeffs"); + error->all(FLERR,"Invalid data file section: Improper Coeffs"); if (force->improper == NULL) - error->all("Must define improper_style before Improper Coeffs"); + error->all(FLERR,"Must define improper_style before Improper Coeffs"); skip_lines(atom->nimpropertypes); } else if (strcmp(keyword,"BondBond Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: BondBond Coeffs"); + error->all(FLERR,"Invalid data file section: BondBond Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before BondBond Coeffs"); + error->all(FLERR,"Must define angle_style before BondBond Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"BondAngle Coeffs") == 0) { if (atom->avec->angles_allow == 0) - error->all("Invalid data file section: BondAngle Coeffs"); + error->all(FLERR,"Invalid data file section: BondAngle Coeffs"); if (force->angle == NULL) - error->all("Must define angle_style before BondAngle Coeffs"); + error->all(FLERR,"Must define angle_style before BondAngle Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: MiddleBondTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: EndBondTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before EndBondTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: AngleTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before AngleTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: AngleAngleTorsion Coeffs"); + error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) - error->all("Invalid data file section: BondBond13 Coeffs"); + error->all(FLERR,"Invalid data file section: BondBond13 Coeffs"); if (force->dihedral == NULL) - error->all("Must define dihedral_style before BondBond13 Coeffs"); + error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) { if (atom->avec->impropers_allow == 0) - error->all("Invalid data file section: AngleAngle Coeffs"); + error->all(FLERR,"Invalid data file section: AngleAngle Coeffs"); if (force->improper == NULL) - error->all("Must define improper_style before AngleAngle Coeffs"); + error->all(FLERR,"Must define improper_style before AngleAngle Coeffs"); skip_lines(atom->nimpropertypes); } else if (strcmp(keyword,"Bonds") == 0) { @@ -1118,7 +1115,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (force->newton_bond) for (i = 0; i < atom->nbonds; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2); if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1); count[atom1]++; @@ -1126,7 +1123,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, else for (i = 0; i < atom->nbonds; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2); int amax = MAX(atom1,atom2); if (amax >= cmax) cmax = reallocate(&count,cmax,amax); @@ -1142,7 +1139,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (force->newton_bond) for (i = 0; i < atom->nangles; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); count[atom2]++; @@ -1150,7 +1147,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, else for (i = 0; i < atom->nangles; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3); int amax = MAX(atom1,atom2); amax = MAX(amax,atom3); @@ -1168,7 +1165,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (force->newton_bond) for (i = 0; i < atom->ndihedrals; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); @@ -1177,7 +1174,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, else for (i = 0; i < atom->ndihedrals; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); int amax = MAX(atom1,atom2); @@ -1201,7 +1198,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (force->newton_bond) for (i = 0; i < atom->nimpropers; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); @@ -1210,7 +1207,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, else for (i = 0; i < atom->nimpropers; i++) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); int amax = MAX(atom1,atom2); @@ -1232,7 +1229,7 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, } else { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); - error->one(str); + error->one(FLERR,str); } parse_keyword(0,0); @@ -1248,13 +1245,13 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, (atom->nangles && !angle_per_atom) || (atom->ndihedrals && !dihedral_per_atom) || (atom->nimpropers && !improper_per_atom)) - error->one("Needed topology not in data file"); + error->one(FLERR,"Needed topology not in data file"); // customize for new sections // error check that Bonus sections were speficied in file if (nellipsoids && !ellipsoid_flag) - error->one("Needed bonus data not in data file"); + error->one(FLERR,"Needed bonus data not in data file"); } /* ---------------------------------------------------------------------- @@ -1288,14 +1285,14 @@ void ReadData::open(char *file) sprintf(gunzip,"gunzip -c %s",file); fp = popen(gunzip,"r"); #else - error->one("Cannot open gzipped file"); + error->one(FLERR,"Cannot open gzipped file"); #endif } if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); - error->one(str); + error->one(FLERR,str); } } @@ -1362,7 +1359,7 @@ void ReadData::skip_lines(int n) { char *eof; for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one("Unexpected end of data file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); } /* ---------------------------------------------------------------------- diff --git a/src/read_restart.cpp b/src/read_restart.cpp index d815b7ff8e..0514cea310 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -69,10 +69,10 @@ ReadRestart::ReadRestart(LAMMPS *lmp) : Pointers(lmp) {} void ReadRestart::command(int narg, char **arg) { - if (narg != 1) error->all("Illegal read_restart command"); + if (narg != 1) error->all(FLERR,"Illegal read_restart command"); if (domain->box_exist) - error->all("Cannot read_restart after simulation box is defined"); + error->all(FLERR,"Cannot read_restart after simulation box is defined"); MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); @@ -112,7 +112,7 @@ void ReadRestart::command(int narg, char **arg) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open restart file %s",hfile); - error->one(str); + error->one(FLERR,str); } if (multiproc) delete [] hfile; } @@ -226,7 +226,7 @@ void ReadRestart::command(int narg, char **arg) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open restart file %s",perproc); - error->one(str); + error->one(FLERR,str); } fread(&n,sizeof(int),1,fp); @@ -307,7 +307,7 @@ void ReadRestart::command(int narg, char **arg) if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } - if (natoms != atom->natoms) error->all("Did not assign all atoms correctly"); + if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); if (me == 0) { if (atom->nbonds) { @@ -411,7 +411,7 @@ void ReadRestart::file_search(char *infile, char *outfile) struct dirent *ep; DIR *dp = opendir(dirname); if (dp == NULL) - error->one("Cannot open dir to search for restart file"); + error->one(FLERR,"Cannot open dir to search for restart file"); while (ep = readdir(dp)) { if (strstr(ep->d_name,begin) != ep->d_name) continue; if ((ptr = strstr(&ep->d_name[nbegin],end)) == NULL) continue; @@ -423,7 +423,7 @@ void ReadRestart::file_search(char *infile, char *outfile) } } closedir(dp); - if (maxnum < 0) error->one("Found no restart file matching pattern"); + if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern"); // create outfile with maxint substituted for "*" // use original infile, not pattern, since need to retain "%" in filename @@ -463,7 +463,7 @@ void ReadRestart::header() if (flag == VERSION) { char *version = read_char(); if (strcmp(version,universe->version) != 0 && me == 0) { - error->warning("Restart file version does not match LAMMPS version"); + error->warning(FLERR,"Restart file version does not match LAMMPS version"); if (screen) fprintf(screen," restart file = %s, LAMMPS = %s\n", version,universe->version); } @@ -474,15 +474,15 @@ void ReadRestart::header() } else if (flag == SMALLINT) { int size = read_int(); if (size != sizeof(smallint)) - error->all("Smallint setting in lmptype.h is not compatible"); + error->all(FLERR,"Smallint setting in lmptype.h is not compatible"); } else if (flag == TAGINT) { int size = read_int(); if (size != sizeof(tagint)) - error->all("Tagint setting in lmptype.h is not compatible"); + error->all(FLERR,"Tagint setting in lmptype.h is not compatible"); } else if (flag == BIGINT) { int size = read_int(); if (size != sizeof(bigint)) - error->all("Bigint setting in lmptype.h is not compatible"); + error->all(FLERR,"Bigint setting in lmptype.h is not compatible"); // reset unit_style only if different // so that timestep,neighbor-skin are not changed @@ -501,14 +501,14 @@ void ReadRestart::header() int dimension = read_int(); domain->dimension = dimension; if (domain->dimension == 2 && domain->zperiodic == 0) - error->all("Cannot run 2d simulation with nonperiodic Z dimension"); + error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension"); // read nprocs from restart file, warn if different } else if (flag == NPROCS) { nprocs_file = read_int(); if (nprocs_file != comm->nprocs && me == 0) - error->warning("Restart file used different # of processors"); + error->warning(FLERR,"Restart file used different # of processors"); // don't set procgrid, warn if different @@ -521,7 +521,7 @@ void ReadRestart::header() if (comm->user_procgrid[0] != 0 && (px != comm->user_procgrid[0] || py != comm->user_procgrid[1] || pz != comm->user_procgrid[2]) && me == 0) - error->warning("Restart file used different 3d processor grid"); + error->warning(FLERR,"Restart file used different 3d processor grid"); // don't set newton_pair, leave input script value unchanged // set newton_bond from restart file @@ -531,14 +531,14 @@ void ReadRestart::header() int newton_pair_file = read_int(); if (force->newton_pair != 1) { if (newton_pair_file != force->newton_pair && me == 0) - error->warning("Restart file used different newton pair setting, " + error->warning(FLERR,"Restart file used different newton pair setting, " "using input script value"); } } else if (flag == NEWTON_BOND) { int newton_bond_file = read_int(); if (force->newton_bond != 1) { if (newton_bond_file != force->newton_bond && me == 0) - error->warning("Restart file used different newton bond setting, " + error->warning(FLERR,"Restart file used different newton bond setting, " "using restart file value"); } force->newton_bond = newton_bond_file; @@ -577,7 +577,7 @@ void ReadRestart::header() boundary[2][0] != domain->boundary[2][0] || boundary[2][1] != domain->boundary[2][1]) { if (me == 0) - error->warning("Restart file used different boundary settings, " + error->warning(FLERR,"Restart file used different boundary settings, " "using restart file values"); } } @@ -687,7 +687,7 @@ void ReadRestart::header() domain->triclinic = 1; domain->yz = read_double(); - } else error->all("Invalid flag in header section of restart file"); + } else error->all(FLERR,"Invalid flag in header section of restart file"); flag = read_int(); } @@ -707,7 +707,7 @@ void ReadRestart::type_arrays() atom->set_mass(mass); delete [] mass; - } else error->all("Invalid flag in type arrays section of restart file"); + } else error->all(FLERR,"Invalid flag in type arrays section of restart file"); flag = read_int(); } @@ -778,7 +778,7 @@ void ReadRestart::force_fields() delete [] style; force->improper->read_restart(fp); - } else error->all("Invalid flag in force field section of restart file"); + } else error->all(FLERR,"Invalid flag in force field section of restart file"); flag = read_int(); } diff --git a/src/region.cpp b/src/region.cpp index 412fcdeff9..d73ebd368a 100644 --- a/src/region.cpp +++ b/src/region.cpp @@ -60,27 +60,27 @@ void Region::init() { if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for region does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(xvar)) - error->all("Variable for region is invalid style"); + error->all(FLERR,"Variable for region is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for region does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(yvar)) - error->all("Variable for region is not equal style"); + error->all(FLERR,"Variable for region is not equal style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for region does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(zvar)) - error->all("Variable for region is not equal style"); + error->all(FLERR,"Variable for region is not equal style"); } if (tstr) { tvar = input->variable->find(tstr); - if (tvar < 0) error->all("Variable name for region does not exist"); + if (tvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(tvar)) - error->all("Variable for region is not equal style"); + error->all(FLERR,"Variable for region is not equal style"); } } @@ -275,7 +275,7 @@ void Region::rotate(double &x, double &y, double &z, double angle) void Region::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal region command"); + if (narg < 0) error->all(FLERR,"Illegal region command"); // option defaults @@ -286,37 +286,37 @@ void Region::options(int narg, char **arg) int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal region command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all("Illegal region command"); + else error->all(FLERR,"Illegal region command"); iarg += 2; } else if (strcmp(arg[iarg],"side") == 0) { - if (iarg+2 > narg) error->all("Illegal region command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"in") == 0) interior = 1; else if (strcmp(arg[iarg+1],"out") == 0) interior = 0; - else error->all("Illegal region command"); + else error->all(FLERR,"Illegal region command"); iarg += 2; } else if (strcmp(arg[iarg],"move") == 0) { - if (iarg+4 > narg) error->all("Illegal region command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"NULL") != 0) { if (strstr(arg[iarg+1],"v_") != arg[iarg+1]) - error->all("Illegal region command"); + error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+1][2]) + 1; xstr = new char[n]; strcpy(xstr,&arg[iarg+1][2]); } if (strcmp(arg[iarg+2],"NULL") != 0) { if (strstr(arg[iarg+2],"v_") != arg[iarg+2]) - error->all("Illegal region command"); + error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+2][2]) + 1; ystr = new char[n]; strcpy(ystr,&arg[iarg+2][2]); } if (strcmp(arg[iarg+3],"NULL") != 0) { if (strstr(arg[iarg+3],"v_") != arg[iarg+3]) - error->all("Illegal region command"); + error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+3][2]) + 1; zstr = new char[n]; strcpy(zstr,&arg[iarg+3][2]); @@ -325,9 +325,9 @@ void Region::options(int narg, char **arg) iarg += 4; } else if (strcmp(arg[iarg],"rotate") == 0) { - if (iarg+8 > narg) error->all("Illegal region command"); + if (iarg+8 > narg) error->all(FLERR,"Illegal region command"); if (strstr(arg[iarg+1],"v_") != arg[iarg+1]) - error->all("Illegal region command"); + error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+1][2]) + 1; tstr = new char[n]; strcpy(tstr,&arg[iarg+1][2]); @@ -339,19 +339,19 @@ void Region::options(int narg, char **arg) axis[2] = atof(arg[iarg+7]); rotateflag = 1; iarg += 8; - } else error->all("Illegal region command"); + } else error->all(FLERR,"Illegal region command"); } // error check if ((moveflag || rotateflag) && (strcmp(style,"union") == 0 || strcmp(style,"intersect") == 0)) - error->all("Region union or intersect cannot be dynamic"); + error->all(FLERR,"Region union or intersect cannot be dynamic"); // setup scaling if (scaleflag && domain->lattice == NULL) - error->all("Use of region with undefined lattice"); + error->all(FLERR,"Use of region with undefined lattice"); if (scaleflag) { xscale = domain->lattice->xlattice; @@ -371,7 +371,7 @@ void Region::options(int narg, char **arg) if (rotateflag) { double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (len == 0.0) - error->all("Region cannot have 0 length rotation vector"); + error->all(FLERR,"Region cannot have 0 length rotation vector"); runit[0] = axis[0]/len; runit[1] = axis[1]/len; runit[2] = axis[2]/len; diff --git a/src/region_block.cpp b/src/region_block.cpp index ff01e7f6a9..cf5eb99208 100644 --- a/src/region_block.cpp +++ b/src/region_block.cpp @@ -21,9 +21,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) @@ -32,7 +29,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[2],"INF") == 0 || strcmp(arg[2],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[2],"INF") == 0) xlo = -BIG; else if (domain->triclinic == 0) xlo = domain->boxlo[0]; else xlo = domain->boxlo_bound[0]; @@ -40,7 +37,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[3],"INF") == 0 || strcmp(arg[3],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[3],"INF") == 0) xhi = BIG; else if (domain->triclinic == 0) xhi = domain->boxhi[0]; else xhi = domain->boxhi_bound[0]; @@ -48,7 +45,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[4],"INF") == 0 || strcmp(arg[4],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[4],"INF") == 0) ylo = -BIG; else if (domain->triclinic == 0) ylo = domain->boxlo[1]; else ylo = domain->boxlo_bound[1]; @@ -56,7 +53,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[5],"INF") == 0 || strcmp(arg[5],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[5],"INF") == 0) yhi = BIG; else if (domain->triclinic == 0) yhi = domain->boxhi[1]; else yhi = domain->boxhi_bound[1]; @@ -64,7 +61,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[6],"INF") == 0) zlo = -BIG; else if (domain->triclinic == 0) zlo = domain->boxlo[2]; else zlo = domain->boxlo_bound[2]; @@ -72,7 +69,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[7],"INF") == 0) zhi = BIG; else if (domain->triclinic == 0) zhi = domain->boxhi[2]; else zhi = domain->boxhi_bound[2]; @@ -81,7 +78,7 @@ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) // error check if (xlo > xhi || ylo > yhi || zlo > zhi) - error->all("Illegal region block command"); + error->all(FLERR,"Illegal region block command"); // extent of block diff --git a/src/region_cone.cpp b/src/region_cone.cpp index c6b94c295c..bfa4e79716 100644 --- a/src/region_cone.cpp +++ b/src/region_cone.cpp @@ -34,7 +34,7 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) : options(narg-9,&arg[9]); if (strcmp(arg[2],"x") && strcmp(arg[2],"y") && strcmp(arg[2],"z")) - error->all("Illegal region cylinder command"); + error->all(FLERR,"Illegal region cylinder command"); axis = arg[2][0]; if (axis == 'x') { @@ -56,7 +56,7 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[7],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[0]; @@ -80,7 +80,7 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[8],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[8],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[0]; @@ -104,11 +104,11 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) : // error check - if (radiuslo < 0.0) error->all("Illegal radius in region cone command"); - if (radiushi < 0.0) error->all("Illegal radius in region cone command"); + if (radiuslo < 0.0) error->all(FLERR,"Illegal radius in region cone command"); + if (radiushi < 0.0) error->all(FLERR,"Illegal radius in region cone command"); if (radiuslo == 0.0 && radiushi == 0.0) - error->all("Illegal radius in region cone command"); - if (hi == lo) error->all("Illegal cone length in region cone command"); + error->all(FLERR,"Illegal radius in region cone command"); + if (hi == lo) error->all(FLERR,"Illegal cone length in region cone command"); // extent of cone diff --git a/src/region_cylinder.cpp b/src/region_cylinder.cpp index 58bb51f212..9aafb9ca87 100644 --- a/src/region_cylinder.cpp +++ b/src/region_cylinder.cpp @@ -22,9 +22,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : @@ -33,7 +30,7 @@ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : options(narg-8,&arg[8]); if (strcmp(arg[2],"x") && strcmp(arg[2],"y") && strcmp(arg[2],"z")) - error->all("Illegal region cylinder command"); + error->all(FLERR,"Illegal region cylinder command"); axis = arg[2][0]; if (axis == 'x') { @@ -52,7 +49,7 @@ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[6],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[0]; @@ -76,7 +73,7 @@ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[7],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[7],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[0]; @@ -100,7 +97,7 @@ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : // error check - if (radius <= 0.0) error->all("Illegal region cylinder command"); + if (radius <= 0.0) error->all(FLERR,"Illegal region cylinder command"); // extent of cylinder diff --git a/src/region_intersect.cpp b/src/region_intersect.cpp index abb959dea3..5618b46b27 100644 --- a/src/region_intersect.cpp +++ b/src/region_intersect.cpp @@ -19,17 +19,14 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ RegIntersect::RegIntersect(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { - if (narg < 5) error->all("Illegal region command"); + if (narg < 5) error->all(FLERR,"Illegal region command"); int n = atoi(arg[2]); - if (n < 2) error->all("Illegal region command"); + if (n < 2) error->all(FLERR,"Illegal region command"); options(narg-(n+3),&arg[n+3]); // build list of regions to intersect @@ -40,7 +37,7 @@ RegIntersect::RegIntersect(LAMMPS *lmp, int narg, char **arg) : int iregion; for (int iarg = 0; iarg < n; iarg++) { iregion = domain->find_region(arg[iarg+3]); - if (iregion == -1) error->all("Region intersect region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Region intersect region ID does not exist"); list[nregion++] = iregion; } diff --git a/src/region_plane.cpp b/src/region_plane.cpp index 45b6f103ab..aa2827422d 100644 --- a/src/region_plane.cpp +++ b/src/region_plane.cpp @@ -36,7 +36,7 @@ RegPlane::RegPlane(LAMMPS *lmp, int narg, char **arg) : // enforce unit normal double rsq = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]; - if (rsq == 0.0) error->all("Illegal region plane command"); + if (rsq == 0.0) error->all(FLERR,"Illegal region plane command"); normal[0] /= sqrt(rsq); normal[1] /= sqrt(rsq); normal[2] /= sqrt(rsq); diff --git a/src/region_prism.cpp b/src/region_prism.cpp index 26d65ab4f7..72f40987cd 100644 --- a/src/region_prism.cpp +++ b/src/region_prism.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; #define BIG 1.0e20 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ RegPrism::RegPrism(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) @@ -38,42 +35,42 @@ RegPrism::RegPrism(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) if (strcmp(arg[2],"INF") == 0 || strcmp(arg[2],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[2],"INF") == 0) xlo = -BIG; else xlo = domain->boxlo[0]; } else xlo = xscale*atof(arg[2]); if (strcmp(arg[3],"INF") == 0 || strcmp(arg[3],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[3],"INF") == 0) xhi = BIG; else xhi = domain->boxhi[0]; } else xhi = xscale*atof(arg[3]); if (strcmp(arg[4],"INF") == 0 || strcmp(arg[4],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[4],"INF") == 0) ylo = -BIG; else ylo = domain->boxlo[1]; } else ylo = yscale*atof(arg[4]); if (strcmp(arg[5],"INF") == 0 || strcmp(arg[5],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[5],"INF") == 0) yhi = BIG; else yhi = domain->boxhi[1]; } else yhi = yscale*atof(arg[5]); if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[6],"INF") == 0) zlo = -BIG; else zlo = domain->boxlo[2]; } else zlo = zscale*atof(arg[6]); if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) - error->all("Cannot use region INF or EDGE when box does not exist"); + error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[7],"INF") == 0) zhi = BIG; else zhi = domain->boxhi[2]; } else zhi = zscale*atof(arg[7]); @@ -87,22 +84,22 @@ RegPrism::RegPrism(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) // non-zero tilt values cannot be used if either dim is INF on both ends if (xlo >= xhi || ylo >= yhi || zlo >= zhi) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (xy != 0.0 && xlo == -BIG && xhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (xy != 0.0 && ylo == -BIG && yhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (xz != 0.0 && xlo == -BIG && xhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (xz != 0.0 && zlo == -BIG && zhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (yz != 0.0 && ylo == -BIG && yhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); if (yz != 0.0 && zlo == -BIG && zhi == BIG) - error->all("Illegal region prism command"); + error->all(FLERR,"Illegal region prism command"); // extent of prism diff --git a/src/region_sphere.cpp b/src/region_sphere.cpp index b03ad6bc23..80446b55a8 100644 --- a/src/region_sphere.cpp +++ b/src/region_sphere.cpp @@ -33,7 +33,7 @@ RegSphere::RegSphere(LAMMPS *lmp, int narg, char **arg) : // error check - if (radius < 0.0) error->all("Illegal region sphere command"); + if (radius < 0.0) error->all(FLERR,"Illegal region sphere command"); // extent of sphere diff --git a/src/region_union.cpp b/src/region_union.cpp index 90a6815cbf..ff566087ef 100644 --- a/src/region_union.cpp +++ b/src/region_union.cpp @@ -19,18 +19,15 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { - if (narg < 5) error->all("Illegal region command"); + if (narg < 5) error->all(FLERR,"Illegal region command"); int n = atoi(arg[2]); - if (n < 2) error->all("Illegal region command"); + if (n < 2) error->all(FLERR,"Illegal region command"); options(narg-(n+3),&arg[n+3]); // build list of regions to union @@ -41,7 +38,7 @@ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) int iregion; for (int iarg = 0; iarg < n; iarg++) { iregion = domain->find_region(arg[iarg+3]); - if (iregion == -1) error->all("Region union region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Region union region ID does not exist"); list[nregion++] = iregion; } diff --git a/src/replicate.cpp b/src/replicate.cpp index b9767e424d..da6a662069 100644 --- a/src/replicate.cpp +++ b/src/replicate.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; #define LB_FACTOR 1.1 #define EPSILON 1.0e-6 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Replicate::Replicate(LAMMPS *lmp) : Pointers(lmp) {} @@ -44,8 +41,8 @@ void Replicate::command(int narg, char **arg) int i,j,m,n; if (domain->box_exist == 0) - error->all("Replicate command before simulation box is defined"); - if (narg != 3) error->all("Illegal replicate command"); + error->all(FLERR,"Replicate command before simulation box is defined"); + if (narg != 3) error->all(FLERR,"Illegal replicate command"); int me = comm->me; int nprocs = comm->nprocs; @@ -61,16 +58,16 @@ void Replicate::command(int narg, char **arg) // error and warning checks - if (nx <= 0 || ny <= 0 || nz <= 0) error->all("Illegal replicate command"); + if (nx <= 0 || ny <= 0 || nz <= 0) error->all(FLERR,"Illegal replicate command"); if (domain->dimension == 2 && nz != 1) - error->all("Cannot replicate 2d simulation in z dimension"); + error->all(FLERR,"Cannot replicate 2d simulation in z dimension"); if ((nx > 1 && domain->xperiodic == 0) || (ny > 1 && domain->yperiodic == 0) || (nz > 1 && domain->zperiodic == 0)) - error->warning("Replicating in a non-periodic dimension"); + error->warning(FLERR,"Replicating in a non-periodic dimension"); if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store) - error->all("Cannot replicate with fixes that store atom quantities"); + error->all(FLERR,"Cannot replicate with fixes that store atom quantities"); // maxtag = largest atom tag across all existing atoms @@ -130,7 +127,7 @@ void Replicate::command(int narg, char **arg) // new system cannot exceed MAXBIGINT if (atom->molecular && (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT)) - error->all("Replicated molecular system atom IDs are too big"); + error->all(FLERR,"Replicated molecular system atom IDs are too big"); if (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT) atom->tag_enable = 0; if (atom->tag_enable == 0) @@ -142,7 +139,7 @@ void Replicate::command(int narg, char **arg) nrep*old->nangles < 0 || nrep*old->nangles > MAXBIGINT || nrep*old->ndihedrals < 0 || nrep*old->ndihedrals > MAXBIGINT || nrep*old->nimpropers < 0 || nrep*old->nimpropers > MAXBIGINT) - error->all("Replicated system is too big"); + error->all(FLERR,"Replicated system is too big"); // assign atom and topology counts in new class from old one @@ -356,7 +353,7 @@ void Replicate::command(int narg, char **arg) } if (natoms != atom->natoms) - error->all("Replicate did not assign all atoms correctly"); + error->all(FLERR,"Replicate did not assign all atoms correctly"); if (me == 0) { if (atom->nbonds) { diff --git a/src/respa.cpp b/src/respa.cpp index 83457da738..c283b6454c 100644 --- a/src/respa.cpp +++ b/src/respa.cpp @@ -45,16 +45,16 @@ using namespace LAMMPS_NS; Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg) { - if (narg < 1) error->all("Illegal run_style respa command"); + if (narg < 1) error->all(FLERR,"Illegal run_style respa command"); nlevels = atoi(arg[0]); - if (nlevels < 1) error->all("Respa levels must be >= 1"); + if (nlevels < 1) error->all(FLERR,"Respa levels must be >= 1"); - if (narg < nlevels) error->all("Illegal run_style respa command"); + if (narg < nlevels) error->all(FLERR,"Illegal run_style respa command"); loop = new int[nlevels]; for (int iarg = 1; iarg < nlevels; iarg++) { loop[iarg-1] = atoi(arg[iarg]); - if (loop[iarg-1] <= 0) error->all("Illegal run_style respa command"); + if (loop[iarg-1] <= 0) error->all(FLERR,"Illegal run_style respa command"); } loop[nlevels-1] = 1; @@ -68,64 +68,64 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg) int iarg = nlevels; while (iarg < narg) { if (strcmp(arg[iarg],"bond") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_bond = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"angle") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_angle = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"dihedral") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_dihedral = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"improper") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_improper = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"pair") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_pair = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"inner") == 0) { - if (iarg+4 > narg) error->all("Illegal run_style respa command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal run_style respa command"); level_inner = atoi(arg[iarg+1]) - 1; cutoff[0] = atof(arg[iarg+2]); cutoff[1] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"middle") == 0) { - if (iarg+4 > narg) error->all("Illegal run_style respa command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal run_style respa command"); level_middle = atoi(arg[iarg+1]) - 1; cutoff[2] = atof(arg[iarg+2]); cutoff[3] = atof(arg[iarg+3]); iarg += 4; } else if (strcmp(arg[iarg],"outer") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_outer = atoi(arg[iarg+1]) - 1; iarg += 2; } else if (strcmp(arg[iarg],"kspace") == 0) { - if (iarg+2 > narg) error->all("Illegal run_style respa command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command"); level_kspace = atoi(arg[iarg+1]) - 1; iarg += 2; - } else error->all("Illegal run_style respa command"); + } else error->all(FLERR,"Illegal run_style respa command"); } // cannot specify both pair and inner/middle/outer if (level_pair >= 0 && (level_inner >= 0 || level_middle >= 0 || level_outer >= 0)) - error->all("Cannot set both respa pair and inner/middle/outer"); + error->all(FLERR,"Cannot set both respa pair and inner/middle/outer"); // if either inner and outer is specified, then both must be if ((level_inner >= 0 && level_outer == -1) || (level_outer >= 0 && level_inner == -1)) - error->all("Must set both respa inner and outer"); + error->all(FLERR,"Must set both respa inner and outer"); // middle cannot be set without inner/outer if (level_middle >= 0 && level_inner == -1) - error->all("Cannot set respa middle without inner/outer"); + error->all(FLERR,"Cannot set respa middle without inner/outer"); // set defaults if user did not specify level // bond to innermost level @@ -183,20 +183,20 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg) if (level_angle < level_bond || level_dihedral < level_angle || level_improper < level_dihedral) - error->all("Invalid order of forces within respa levels"); + error->all(FLERR,"Invalid order of forces within respa levels"); if (level_pair >= 0) { if (level_pair < level_improper || level_kspace < level_pair) - error->all("Invalid order of forces within respa levels"); + error->all(FLERR,"Invalid order of forces within respa levels"); } if (level_pair == -1 && level_middle == -1) { if (level_inner < level_improper || level_outer < level_inner || level_kspace != level_outer) - error->all("Invalid order of forces within respa levels"); + error->all(FLERR,"Invalid order of forces within respa levels"); } if (level_pair == -1 && level_middle >= 0) { if (level_inner < level_improper || level_middle < level_inner || level_outer < level_inner || level_kspace != level_outer) - error->all("Invalid order of forces within respa levels"); + error->all(FLERR,"Invalid order of forces within respa levels"); } // warn if any levels are devoid of forces @@ -207,14 +207,14 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg) level_improper != i && level_pair != i && level_inner != i && level_middle != i && level_outer != i && level_kspace != i) flag = 1; if (flag && comm->me == 0) - error->warning("One or more respa levels compute no forces"); + error->warning(FLERR,"One or more respa levels compute no forces"); // check cutoff consistency if inner/middle/outer are enabled if (level_inner >= 0 && cutoff[1] < cutoff[0]) - error->all("Respa inner cutoffs are invalid"); + error->all(FLERR,"Respa inner cutoffs are invalid"); if (level_middle >= 0 && (cutoff[3] < cutoff[2] || cutoff[2] < cutoff[1])) - error->all("Respa middle cutoffs are invalid"); + error->all(FLERR,"Respa middle cutoffs are invalid"); // set outer pair of cutoffs to inner pair if middle is not enabled @@ -247,7 +247,7 @@ void Respa::init() // warn if no fixes if (modify->nfix == 0 && comm->me == 0) - error->warning("No fixes defined, atoms won't move"); + error->warning(FLERR,"No fixes defined, atoms won't move"); // create fix needed for storing atom-based respa level forces // will delete it at end of run @@ -267,7 +267,7 @@ void Respa::init() if (level_inner >= 0) if (force->pair && force->pair->respa_enable == 0) - error->all("Pair style does not support rRESPA inner/middle/outer"); + error->all(FLERR,"Pair style does not support rRESPA inner/middle/outer"); // virial_style = 1 (explicit) since never computed implicitly like Verlet diff --git a/src/run.cpp b/src/run.cpp index 667ea84a80..1f413072a0 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -27,9 +27,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - #define MAXLINE 2048 /* ---------------------------------------------------------------------- */ @@ -40,10 +37,10 @@ Run::Run(LAMMPS *lmp) : Pointers(lmp) {} void Run::command(int narg, char **arg) { - if (narg < 1) error->all("Illegal run command"); + if (narg < 1) error->all(FLERR,"Illegal run command"); if (domain->box_exist == 0) - error->all("Run command before simulation box is defined"); + error->all(FLERR,"Run command before simulation box is defined"); bigint nsteps_input = ATOBIGINT(arg[0]); @@ -62,30 +59,30 @@ void Run::command(int narg, char **arg) int iarg = 1; while (iarg < narg) { if (strcmp(arg[iarg],"upto") == 0) { - if (iarg+1 > narg) error->all("Illegal run command"); + if (iarg+1 > narg) error->all(FLERR,"Illegal run command"); uptoflag = 1; iarg += 1; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all("Illegal run command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run command"); startflag = 1; start = ATOBIGINT(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"stop") == 0) { - if (iarg+2 > narg) error->all("Illegal run command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run command"); stopflag = 1; stop = ATOBIGINT(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"pre") == 0) { - if (iarg+2 > narg) error->all("Illegal run command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run command"); if (strcmp(arg[iarg+1],"no") == 0) preflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) preflag = 1; - else error->all("Illegal run command"); + else error->all(FLERR,"Illegal run command"); iarg += 2; } else if (strcmp(arg[iarg],"post") == 0) { - if (iarg+2 > narg) error->all("Illegal run command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal run command"); if (strcmp(arg[iarg+1],"no") == 0) postflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) postflag = 1; - else error->all("Illegal run command"); + else error->all(FLERR,"Illegal run command"); iarg += 2; // all remaining args are commands @@ -93,15 +90,15 @@ void Run::command(int narg, char **arg) // set ncommands = 0 if single command and it is NULL } else if (strcmp(arg[iarg],"every") == 0) { - if (iarg+3 > narg) error->all("Illegal run command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal run command"); nevery = atoi(arg[iarg+1]); - if (nevery <= 0) error->all("Illegal run command"); + if (nevery <= 0) error->all(FLERR,"Illegal run command"); first = iarg+2; last = narg-1; ncommands = last-first + 1; if (ncommands == 1 && strcmp(arg[first],"NULL") == 0) ncommands = 0; iarg = narg; - } else error->all("Illegal run command"); + } else error->all(FLERR,"Illegal run command"); } // set nsteps as integer, using upto value if specified @@ -109,12 +106,12 @@ void Run::command(int narg, char **arg) int nsteps; if (!uptoflag) { if (nsteps_input < 0 || nsteps_input > MAXSMALLINT) - error->all("Invalid run command N value"); + error->all(FLERR,"Invalid run command N value"); nsteps = static_cast (nsteps_input); } else { bigint delta = nsteps_input - update->ntimestep; if (delta < 0 || delta > MAXSMALLINT) - error->all("Invalid run command upto value"); + error->all(FLERR,"Invalid run command upto value"); nsteps = static_cast (delta); } @@ -122,15 +119,15 @@ void Run::command(int narg, char **arg) if (startflag) { if (start < 0 || start > MAXBIGINT) - error->all("Invalid run command start/stop value"); + error->all(FLERR,"Invalid run command start/stop value"); if (start > update->ntimestep) - error->all("Run command start value is after start of run"); + error->all(FLERR,"Run command start value is after start of run"); } if (stopflag) { if (stop < 0 || stop > MAXBIGINT) - error->all("Invalid run command start/stop value"); + error->all(FLERR,"Invalid run command start/stop value"); if (stop < update->ntimestep + nsteps) - error->all("Run command stop value is before end of run"); + error->all(FLERR,"Run command stop value is before end of run"); } // if nevery, make copies of arg strings that are commands @@ -161,7 +158,7 @@ void Run::command(int narg, char **arg) update->firststep = update->ntimestep; update->laststep = update->ntimestep + nsteps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); if (startflag) update->beginstep = start; else update->beginstep = update->firststep; @@ -201,7 +198,7 @@ void Run::command(int narg, char **arg) update->firststep = update->ntimestep; update->laststep = update->ntimestep + nsteps; if (update->laststep < 0 || update->laststep > MAXBIGINT) - error->all("Too many timesteps"); + error->all(FLERR,"Too many timesteps"); if (startflag) update->beginstep = start; else update->beginstep = update->firststep; diff --git a/src/set.cpp b/src/set.cpp index a541fcca98..be3cd5867d 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -52,10 +52,10 @@ Set::Set(LAMMPS *lmp) : Pointers(lmp) void Set::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Set command before simulation box is defined"); + error->all(FLERR,"Set command before simulation box is defined"); if (atom->natoms == 0) - error->all("Set command with no atoms existing"); - if (narg < 3) error->all("Illegal set command"); + error->all(FLERR,"Set command with no atoms existing"); + if (narg < 3) error->all(FLERR,"Illegal set command"); // style and ID info @@ -64,7 +64,7 @@ void Set::command(int narg, char **arg) else if (strcmp(arg[0],"type") == 0) style = TYPE_SELECT; else if (strcmp(arg[0],"group") == 0) style = GROUP_SELECT; else if (strcmp(arg[0],"region") == 0) style = REGION_SELECT; - else error->all("Illegal set command"); + else error->all(FLERR,"Illegal set command"); int n = strlen(arg[1]) + 1; id = new char[n]; @@ -84,137 +84,137 @@ void Set::command(int narg, char **arg) origarg = iarg; if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (ivalue <= 0 || ivalue > atom->ntypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); set(TYPE); iarg += 2; } else if (strcmp(arg[iarg],"type/fraction") == 0) { - if (iarg+4 > narg) error->all("Illegal set command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); newtype = atoi(arg[iarg+1]); fraction = atof(arg[iarg+2]); ivalue = atoi(arg[iarg+3]); if (newtype <= 0 || newtype > atom->ntypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); if (fraction < 0.0 || fraction > 1.0) - error->all("Invalid value in set command"); - if (ivalue <= 0) error->all("Invalid random number seed in set command"); + error->all(FLERR,"Invalid value in set command"); + if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); setrandom(TYPE_FRACTION); iarg += 4; } else if (strcmp(arg[iarg],"mol") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (!atom->molecule_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(MOLECULE); iarg += 2; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); set(X); iarg += 2; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); set(Y); iarg += 2; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); set(Z); iarg += 2; } else if (strcmp(arg[iarg],"charge") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->q_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(CHARGE); iarg += 2; } else if (strcmp(arg[iarg],"mass") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->rmass_flag) - error->all("Cannot set this attribute for this atom style"); - if (dvalue <= 0.0) error->all("Invalid mass in set command"); + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue <= 0.0) error->all(FLERR,"Invalid mass in set command"); set(MASS); iarg += 2; } else if (strcmp(arg[iarg],"shape") == 0) { - if (iarg+4 > narg) error->all("Illegal set command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); xvalue = atof(arg[iarg+1]); yvalue = atof(arg[iarg+2]); zvalue = atof(arg[iarg+3]); if (!atom->ellipsoid_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); if (xvalue < 0.0 || yvalue < 0.0 || zvalue < 0.0) - error->all("Invalid shape in set command"); + error->all(FLERR,"Invalid shape in set command"); if (xvalue > 0.0 || yvalue > 0.0 || zvalue > 0.0) { if (xvalue == 0.0 || yvalue == 0.0 || zvalue == 0.0) - error->one("Invalid shape in set command"); + error->one(FLERR,"Invalid shape in set command"); } set(SHAPE); iarg += 4; } else if (strcmp(arg[iarg],"dipole") == 0) { - if (iarg+4 > narg) error->all("Illegal set command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); xvalue = atof(arg[iarg+1]); yvalue = atof(arg[iarg+2]); zvalue = atof(arg[iarg+3]); if (!atom->mu_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(DIPOLE); iarg += 4; } else if (strcmp(arg[iarg],"dipole/random") == 0) { - if (iarg+3 > narg) error->all("Illegal set command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); dvalue = atof(arg[iarg+2]); if (!atom->mu_flag) - error->all("Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all("Invalid random number seed in set command"); - if (dvalue <= 0.0) error->all("Invalid dipole length in set command"); + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); + if (dvalue <= 0.0) error->all(FLERR,"Invalid dipole length in set command"); setrandom(DIPOLE_RANDOM); iarg += 3; } else if (strcmp(arg[iarg],"quat") == 0) { - if (iarg+5 > narg) error->all("Illegal set command"); + if (iarg+5 > narg) error->all(FLERR,"Illegal set command"); xvalue = atof(arg[iarg+1]); yvalue = atof(arg[iarg+2]); zvalue = atof(arg[iarg+3]); wvalue = atof(arg[iarg+4]); if (!atom->ellipsoid_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(QUAT); iarg += 5; } else if (strcmp(arg[iarg],"quat/random") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (!atom->ellipsoid_flag) - error->all("Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all("Invalid random number seed in set command"); + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"diameter") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->radius_flag) - error->all("Cannot set this attribute for this atom style"); - if (dvalue < 0.0) error->all("Invalid diameter in set command"); + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue < 0.0) error->all(FLERR,"Invalid diameter in set command"); set(DIAMETER); iarg += 2; } else if (strcmp(arg[iarg],"density") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->rmass_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(DENSITY); iarg += 2; } else if (strcmp(arg[iarg],"volume") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->vfrac_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(VOLUME); iarg += 2; } else if (strcmp(arg[iarg],"image") == 0) { - if (iarg+4 > narg) error->all("Illegal set command"); + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); ximageflag = yimageflag = zimageflag = 0; if (strcmp(arg[iarg+1],"NULL") != 0) { ximageflag = 1; @@ -229,71 +229,71 @@ void Set::command(int narg, char **arg) zimage = atoi(arg[iarg+3]); } if (ximageflag && ximage && !domain->xperiodic) - error->all("Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); if (yimageflag && yimage && !domain->yperiodic) - error->all("Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); if (zimageflag && zimage && !domain->zperiodic) - error->all("Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); set(IMAGE); iarg += 4; } else if (strcmp(arg[iarg],"bond") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (atom->avec->bonds_allow == 0) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0 || ivalue > atom->nbondtypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); topology(BOND); iarg += 2; } else if (strcmp(arg[iarg],"angle") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (atom->avec->angles_allow == 0) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0 || ivalue > atom->nangletypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); topology(ANGLE); iarg += 2; } else if (strcmp(arg[iarg],"dihedral") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (atom->avec->dihedrals_allow == 0) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0 || ivalue > atom->ndihedraltypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); topology(DIHEDRAL); iarg += 2; } else if (strcmp(arg[iarg],"improper") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); if (atom->avec->impropers_allow == 0) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0 || ivalue > atom->nimpropertypes) - error->all("Invalid value in set command"); + error->all(FLERR,"Invalid value in set command"); topology(IMPROPER); iarg += 2; } else if (strcmp(arg[iarg],"meso_e") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->e_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(MESO_E); iarg += 2; } else if (strcmp(arg[iarg],"meso_cv") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->cv_flag) - error->all("Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set this attribute for this atom style"); set(MESO_CV); iarg += 2; } else if (strcmp(arg[iarg],"meso_rho") == 0) { - if (iarg+2 > narg) error->all("Illegal set command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); if (!atom->rho_flag) - error->all("Cannot set meso_rho for this atom style"); + error->all(FLERR,"Cannot set meso_rho for this atom style"); set(MESO_RHO); iarg += 2; - } else error->all("Illegal set command"); + } else error->all(FLERR,"Illegal set command"); // statistics @@ -326,7 +326,7 @@ void Set::selection(int n) if (style == ATOM_SELECT) { if (atom->tag_enable == 0) - error->all("Cannot use set atom with no atom IDs defined"); + error->all(FLERR,"Cannot use set atom with no atom IDs defined"); force->bounds(id,BIG,nlo,nhi); int *tag = atom->tag; @@ -336,7 +336,7 @@ void Set::selection(int n) } else if (style == MOL_SELECT) { if (atom->molecule_flag == 0) - error->all("Cannot use set mol with no molecule IDs defined"); + error->all(FLERR,"Cannot use set mol with no molecule IDs defined"); if (strcmp(id,"0") == 0) nlo = nhi = 0; else force->bounds(id,BIG,nlo,nhi); @@ -355,7 +355,7 @@ void Set::selection(int n) } else if (style == GROUP_SELECT) { int igroup = group->find(id); - if (igroup == -1) error->all("Could not find set group ID"); + if (igroup == -1) error->all(FLERR,"Could not find set group ID"); int groupbit = group->bitmask[igroup]; int *mask = atom->mask; @@ -365,7 +365,7 @@ void Set::selection(int n) } else if (style == REGION_SELECT) { int iregion = domain->find_region(id); - if (iregion == -1) error->all("Set region ID does not exist"); + if (iregion == -1) error->all(FLERR,"Set region ID does not exist"); double **x = atom->x; for (int i = 0; i < n; i++) @@ -448,7 +448,7 @@ void Set::set(int keyword) } else if (keyword == QUAT) { if (atom->ellipsoid[i] < 0) - error->one("Cannot set quaternion for atom that is not an ellipsoid"); + error->one(FLERR,"Cannot set quaternion for atom that is not an ellipsoid"); double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; double theta2 = 0.5 * PI * wvalue/180.0; double sintheta2 = sin(theta2); @@ -547,7 +547,7 @@ void Set::setrandom(int keyword) for (i = 0; i < nlocal; i++) if (select[i]) { if (ellipsoid[i] < 0) - error->one("Cannot set quaternion for atom " + error->one(FLERR,"Cannot set quaternion for atom " "that is not an ellipsoid"); quat = bonus[ellipsoid[i]].quat; random->reset(seed,x[i]); @@ -568,7 +568,7 @@ void Set::setrandom(int keyword) for (i = 0; i < nlocal; i++) if (select[i]) { if (ellipsoid[i] < 0) - error->one("Cannot set quaternion for atom " + error->one(FLERR,"Cannot set quaternion for atom " "that is not an ellipsoid"); quat = bonus[ellipsoid[i]].quat; random->reset(seed,x[i]); @@ -618,7 +618,7 @@ void Set::topology(int keyword) for (int i = 0; i < nlocal; i++) for (m = 0; m < atom->num_bond[i]; m++) { atom1 = atom->map(atom->bond_atom[i][m]); - if (atom1 == -1) error->one("Bond atom missing in set command"); + if (atom1 == -1) error->one(FLERR,"Bond atom missing in set command"); if (select[i] && select[atom1]) { atom->bond_type[i][m] = ivalue; count++; @@ -636,7 +636,7 @@ void Set::topology(int keyword) atom2 = atom->map(atom->angle_atom2[i][m]); atom3 = atom->map(atom->angle_atom3[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1) - error->one("Angle atom missing in set command"); + error->one(FLERR,"Angle atom missing in set command"); if (select[atom1] && select[atom2] && select[atom3]) { atom->angle_type[i][m] = ivalue; count++; @@ -655,7 +655,7 @@ void Set::topology(int keyword) atom3 = atom->map(atom->dihedral_atom3[i][m]); atom4 = atom->map(atom->dihedral_atom4[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) - error->one("Dihedral atom missing in set command"); + error->one(FLERR,"Dihedral atom missing in set command"); if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) { atom->dihedral_type[i][m] = ivalue; count++; @@ -674,7 +674,7 @@ void Set::topology(int keyword) atom3 = atom->map(atom->improper_atom3[i][m]); atom4 = atom->map(atom->improper_atom4[i][m]); if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) - error->one("Improper atom missing in set command"); + error->one(FLERR,"Improper atom missing in set command"); if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) { atom->improper_type[i][m] = ivalue; count++; diff --git a/src/special.cpp b/src/special.cpp index e0ec4ce317..189b2374fb 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -22,9 +22,6 @@ using namespace LAMMPS_NS; -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Special::Special(LAMMPS *lmp) : Pointers(lmp) @@ -374,7 +371,7 @@ void Special::build() j = 0; for (i = 0; i < nlocal; i++) { if (buf[j+3] != nspecial[i][1]) - error->one("1-3 bond count is inconsistent"); + error->one(FLERR,"1-3 bond count is inconsistent"); j += 4 + nspecial[i][0]; for (k = 0; k < nspecial[i][1]; k++) onethree[i][k] = buf[j++]; @@ -537,7 +534,7 @@ void Special::build() j = 0; for (i = 0; i < nlocal; i++) { if (buf[j+2] != nspecial[i][2]) - error->one("1-4 bond count is inconsistent"); + error->one(FLERR,"1-4 bond count is inconsistent"); j += 3 + nspecial[i][1]; for (k = 0; k < nspecial[i][2]; k++) onefour[i][k] = buf[j++]; diff --git a/src/thermo.cpp b/src/thermo.cpp index 1653de8f42..5bd877191a 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -68,9 +68,6 @@ enum{SCALAR,VECTOR,ARRAY}; #define MAXLINE 8192 // make this 4x longer than Input::MAXLINE #define DELTA 8 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - /* ---------------------------------------------------------------------- */ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) @@ -103,7 +100,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) lineflag = MULTILINE; } else if (strcmp(style,"custom") == 0) { - if (narg == 1) error->all("Illegal thermo style custom command"); + if (narg == 1) error->all(FLERR,"Illegal thermo style custom command"); line[0] = '\0'; for (int iarg = 1; iarg < narg; iarg++) { strcat(line,arg[iarg]); @@ -111,7 +108,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } line[strlen(line)-1] = '\0'; - } else error->all("Illegal thermo style command"); + } else error->all(FLERR,"Illegal thermo style command"); // ptrs, flags, IDs for compute objects thermo may use or create @@ -229,7 +226,7 @@ void Thermo::init() int icompute; for (i = 0; i < ncompute; i++) { icompute = modify->find_compute(id_compute[i]); - if (icompute < 0) error->all("Could not find thermo compute ID"); + if (icompute < 0) error->all(FLERR,"Could not find thermo compute ID"); computes[i] = modify->compute[icompute]; cudable = cudable && computes[i]->cudable; } @@ -240,10 +237,10 @@ void Thermo::init() int ifix; for (i = 0; i < nfix; i++) { ifix = modify->find_fix(id_fix[i]); - if (ifix < 0) error->all("Could not find thermo fix ID"); + if (ifix < 0) error->all(FLERR,"Could not find thermo fix ID"); fixes[i] = modify->fix[ifix]; if (output->thermo_every % fixes[i]->global_freq) - error->all("Thermo and fix not computed at compatible times"); + error->all(FLERR,"Thermo and fix not computed at compatible times"); } // find current ptr for each Variable ID @@ -252,7 +249,7 @@ void Thermo::init() for (i = 0; i < nvariable; i++) { ivariable = input->variable->find(id_variable[i]); if (ivariable < 0) - error->all("Could not find thermo custom variable name"); + error->all(FLERR,"Could not find thermo custom variable name"); variables[i] = ivariable; } @@ -366,7 +363,7 @@ bigint Thermo::lost_check() bigint ntotal; bigint nblocal = atom->nlocal; MPI_Allreduce(&nblocal,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); - if (ntotal < 0 || ntotal > MAXBIGINT) error->all("Too many total atoms"); + if (ntotal < 0 || ntotal > MAXBIGINT) error->all(FLERR,"Too many total atoms"); if (ntotal == atom->natoms) return ntotal; // if not checking or already warned, just return @@ -385,7 +382,7 @@ bigint Thermo::lost_check() sprintf(str, "Lost atoms: original " BIGINT_FORMAT " current " BIGINT_FORMAT, atom->natoms,ntotal); - error->all(str); + error->all(FLERR,str); } // warning message @@ -394,7 +391,7 @@ bigint Thermo::lost_check() sprintf(str, "Lost atoms: original " BIGINT_FORMAT " current " BIGINT_FORMAT, atom->natoms,ntotal); - if (me == 0) error->warning(str,0); + if (me == 0) error->warning(FLERR,str,0); // reset total atom count @@ -409,25 +406,25 @@ bigint Thermo::lost_check() void Thermo::modify_params(int narg, char **arg) { - if (narg == 0) error->all("Illegal thermo_modify command"); + if (narg == 0) error->all(FLERR,"Illegal thermo_modify command"); modified = 1; int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"every") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { delete [] output->var_thermo; int n = strlen(&arg[iarg+1][2]) + 1; output->var_thermo = new char[n]; strcpy(output->var_thermo,&arg[iarg+1][2]); - } else error->all("Illegal thermo_modify command"); + } else error->all(FLERR,"Illegal thermo_modify command"); output->thermo_every = 0; iarg += 2; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); - if (index_temp < 0) error->all("Thermo style does not use temp"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); + if (index_temp < 0) error->all(FLERR,"Thermo style does not use temp"); delete [] id_compute[index_temp]; int n = strlen(arg[iarg+1]) + 1; id_compute[index_temp] = new char[n]; @@ -435,24 +432,24 @@ void Thermo::modify_params(int narg, char **arg) int icompute = modify->find_compute(arg[iarg+1]); if (icompute < 0) - error->all("Could not find thermo_modify temperature ID"); + error->all(FLERR,"Could not find thermo_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Thermo_modify temperature ID does not " + error->all(FLERR,"Thermo_modify temperature ID does not " "compute temperature"); if (temperature->igroup != 0 && comm->me == 0) - error->warning("Temperature for thermo pressure is not for group all"); + error->warning(FLERR,"Temperature for thermo pressure is not for group all"); // reset id_temp of pressure to new temperature ID // either pressure currently being used by thermo or "thermo_press" if (index_press_scalar >= 0) { icompute = modify->find_compute(id_compute[index_press_scalar]); - if (icompute < 0) error->all("Pressure ID for thermo does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for thermo does not exist"); } else if (index_press_vector >= 0) { icompute = modify->find_compute(id_compute[index_press_vector]); - if (icompute < 0) error->all("Pressure ID for thermo does not exist"); + if (icompute < 0) error->all(FLERR,"Pressure ID for thermo does not exist"); } else icompute = modify->find_compute((char *) "thermo_press"); modify->compute[icompute]->reset_extra_compute_fix(arg[iarg+1]); @@ -460,9 +457,9 @@ void Thermo::modify_params(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg],"press") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (index_press_scalar < 0 && index_press_vector < 0) - error->all("Thermo style does not use press"); + error->all(FLERR,"Thermo style does not use press"); if (index_press_scalar >= 0) { delete [] id_compute[index_press_scalar]; @@ -478,46 +475,46 @@ void Thermo::modify_params(int narg, char **arg) } int icompute = modify->find_compute(arg[iarg+1]); - if (icompute < 0) error->all("Could not find thermo_modify pressure ID"); + if (icompute < 0) error->all(FLERR,"Could not find thermo_modify pressure ID"); pressure = modify->compute[icompute]; if (pressure->pressflag == 0) - error->all("Thermo_modify pressure ID does not compute pressure"); + error->all(FLERR,"Thermo_modify pressure ID does not compute pressure"); iarg += 2; } else if (strcmp(arg[iarg],"lost") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (strcmp(arg[iarg+1],"ignore") == 0) lostflag = IGNORE; else if (strcmp(arg[iarg+1],"warn") == 0) lostflag = WARN; else if (strcmp(arg[iarg+1],"error") == 0) lostflag = ERROR; - else error->all("Illegal thermo_modify command"); + else error->all(FLERR,"Illegal thermo_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"norm") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); normuserflag = 1; if (strcmp(arg[iarg+1],"no") == 0) normuser = 0; else if (strcmp(arg[iarg+1],"yes") == 0) normuser = 1; - else error->all("Illegal thermo_modify command"); + else error->all(FLERR,"Illegal thermo_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"flush") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (strcmp(arg[iarg+1],"no") == 0) flushflag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) flushflag = 1; - else error->all("Illegal thermo_modify command"); + else error->all(FLERR,"Illegal thermo_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"line") == 0) { - if (iarg+2 > narg) error->all("Illegal thermo_modify command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (strcmp(arg[iarg+1],"one") == 0) lineflag = ONELINE; else if (strcmp(arg[iarg+1],"multi") == 0) lineflag = MULTILINE; - else error->all("Illegal thermo_modify command"); + else error->all(FLERR,"Illegal thermo_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"format") == 0) { - if (iarg+3 > narg) error->all("Illegal thermo_modify command"); + if (iarg+3 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (strcmp(arg[iarg+1],"int") == 0) { if (format_int_user) delete [] format_int_user; int n = strlen(arg[iarg+2]) + 1; @@ -528,7 +525,7 @@ void Thermo::modify_params(int narg, char **arg) format_bigint_user = new char[n]; char *ptr = strchr(format_int_user,'d'); if (ptr == NULL) - error->all("Thermo_modify int format does not contain d character"); + error->all(FLERR,"Thermo_modify int format does not contain d character"); *ptr = '\0'; sprintf(format_bigint_user,"%s%s%s",format_int_user, BIGINT_FORMAT,ptr+1); @@ -541,7 +538,7 @@ void Thermo::modify_params(int narg, char **arg) } else { int i = atoi(arg[iarg+1]) - 1; if (i < 0 || i >= nfield_initial) - error->all("Illegal thermo_modify command"); + error->all(FLERR,"Illegal thermo_modify command"); if (format_user[i]) delete [] format_user[i]; int n = strlen(arg[iarg+2]) + 1; format_user[i] = new char[n]; @@ -549,7 +546,7 @@ void Thermo::modify_params(int narg, char **arg) } iarg += 3; - } else error->all("Illegal thermo_modify command"); + } else error->all(FLERR,"Illegal thermo_modify command"); } } @@ -744,15 +741,15 @@ void Thermo::parse_fields(char *str) } else if (strcmp(word,"xlat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword requires lattice be defined"); + error->all(FLERR,"Thermo keyword requires lattice be defined"); addfield("Xlat",&Thermo::compute_xlat,FLOAT); } else if (strcmp(word,"ylat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword requires lattice be defined"); + error->all(FLERR,"Thermo keyword requires lattice be defined"); addfield("Ylat",&Thermo::compute_ylat,FLOAT); } else if (strcmp(word,"zlat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword requires lattice be defined"); + error->all(FLERR,"Thermo keyword requires lattice be defined"); addfield("Zlat",&Thermo::compute_zlat,FLOAT); } else if (strcmp(word,"pxx") == 0) { @@ -823,21 +820,21 @@ void Thermo::parse_fields(char *str) if (word[0] == 'c') { n = modify->find_compute(id); - if (n < 0) error->all("Could not find thermo custom compute ID"); + if (n < 0) error->all(FLERR,"Could not find thermo custom compute ID"); if (argindex1[nfield] == 0 && modify->compute[n]->scalar_flag == 0) - error->all("Thermo compute does not compute scalar"); + error->all(FLERR,"Thermo compute does not compute scalar"); if (argindex1[nfield] > 0 && argindex2[nfield] == 0) { if (modify->compute[n]->vector_flag == 0) - error->all("Thermo compute does not compute vector"); + error->all(FLERR,"Thermo compute does not compute vector"); if (argindex1[nfield] > modify->compute[n]->size_vector) - error->all("Thermo compute vector is accessed out-of-range"); + error->all(FLERR,"Thermo compute vector is accessed out-of-range"); } if (argindex1[nfield] > 0 && argindex2[nfield] > 0) { if (modify->compute[n]->array_flag == 0) - error->all("Thermo compute does not compute array"); + error->all(FLERR,"Thermo compute does not compute array"); if (argindex1[nfield] > modify->compute[n]->size_array_rows || argindex2[nfield] > modify->compute[n]->size_array_cols) - error->all("Thermo compute array is accessed out-of-range"); + error->all(FLERR,"Thermo compute array is accessed out-of-range"); } if (argindex1[nfield] == 0) @@ -850,21 +847,21 @@ void Thermo::parse_fields(char *str) } else if (word[0] == 'f') { n = modify->find_fix(id); - if (n < 0) error->all("Could not find thermo custom fix ID"); + if (n < 0) error->all(FLERR,"Could not find thermo custom fix ID"); if (argindex1[nfield] == 0 && modify->fix[n]->scalar_flag == 0) - error->all("Thermo fix does not compute scalar"); + error->all(FLERR,"Thermo fix does not compute scalar"); if (argindex1[nfield] > 0 && argindex2[nfield] == 0) { if (modify->fix[n]->vector_flag == 0) - error->all("Thermo fix does not compute vector"); + error->all(FLERR,"Thermo fix does not compute vector"); if (argindex1[nfield] > modify->fix[n]->size_vector) - error->all("Thermo fix vector is accessed out-of-range"); + error->all(FLERR,"Thermo fix vector is accessed out-of-range"); } if (argindex1[nfield] > 0 && argindex2[nfield] > 0) { if (modify->fix[n]->array_flag == 0) - error->all("Thermo fix does not compute array"); + error->all(FLERR,"Thermo fix does not compute array"); if (argindex1[nfield] > modify->fix[n]->size_array_rows || argindex2[nfield] > modify->fix[n]->size_array_cols) - error->all("Thermo fix array is accessed out-of-range"); + error->all(FLERR,"Thermo fix array is accessed out-of-range"); } field2index[nfield] = add_fix(id); @@ -872,11 +869,11 @@ void Thermo::parse_fields(char *str) } else if (word[0] == 'v') { n = input->variable->find(id); - if (n < 0) error->all("Could not find thermo custom variable name"); + if (n < 0) error->all(FLERR,"Could not find thermo custom variable name"); if (input->variable->equalstyle(n) == 0) - error->all("Thermo custom variable is not equal-style variable"); + error->all(FLERR,"Thermo custom variable is not equal-style variable"); if (argindex1[nfield]) - error->all("Thermo custom variable cannot be indexed"); + error->all(FLERR,"Thermo custom variable cannot be indexed"); field2index[nfield] = add_variable(id); addfield(copy,&Thermo::compute_variable,FLOAT); @@ -884,7 +881,7 @@ void Thermo::parse_fields(char *str) delete [] id; - } else error->all("Invalid keyword in thermo_style custom command"); + } else error->all(FLERR,"Invalid keyword in thermo_style custom command"); word = strtok(NULL," \0"); } @@ -974,13 +971,13 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"elapsed") == 0) { if (update->whichflag == 0) - error->all("This variable thermo keyword cannot be used between runs"); + error->all(FLERR,"This variable thermo keyword cannot be used between runs"); compute_elapsed(); dvalue = bivalue; } else if (strcmp(word,"elaplong") == 0) { if (update->whichflag == 0) - error->all("This variable thermo keyword cannot be used between runs"); + error->all(FLERR,"This variable thermo keyword cannot be used between runs"); compute_elapsed_long(); dvalue = bivalue; @@ -989,17 +986,17 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"cpu") == 0) { if (update->whichflag == 0) - error->all("This variable thermo keyword cannot be used between runs"); + error->all(FLERR,"This variable thermo keyword cannot be used between runs"); compute_cpu(); } else if (strcmp(word,"tpcpu") == 0) { if (update->whichflag == 0) - error->all("This variable thermo keyword cannot be used between runs"); + error->all(FLERR,"This variable thermo keyword cannot be used between runs"); compute_tpcpu(); } else if (strcmp(word,"spcpu") == 0) { if (update->whichflag == 0) - error->all("This variable thermo keyword cannot be used between runs"); + error->all(FLERR,"This variable thermo keyword cannot be used between runs"); compute_spcpu(); } else if (strcmp(word,"atoms") == 0) { @@ -1008,11 +1005,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"temp") == 0) { if (!temperature) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init temp"); if (update->whichflag == 0) { if (temperature->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) { temperature->compute_scalar(); @@ -1022,11 +1019,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"press") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_SCALAR)) { pressure->compute_scalar(); @@ -1036,10 +1033,10 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pe") == 0) { if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); if (update->whichflag == 0) { if (pe->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pe->invoked_flag & INVOKED_SCALAR)) { pe->compute_scalar(); @@ -1049,11 +1046,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"ke") == 0) { if (!temperature) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init temp"); if (update->whichflag == 0) { if (temperature->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) { temperature->compute_scalar(); @@ -1063,21 +1060,21 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"etotal") == 0) { if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); if (update->whichflag == 0) { if (pe->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pe->invoked_flag & INVOKED_SCALAR)) { pe->compute_scalar(); pe->invoked_flag |= INVOKED_SCALAR; } if (!temperature) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init temp"); if (update->whichflag == 0) { if (temperature->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) { temperature->compute_scalar(); @@ -1087,32 +1084,32 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"enthalpy") == 0) { if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); if (update->whichflag == 0) { if (pe->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pe->invoked_flag & INVOKED_SCALAR)) { pe->compute_scalar(); pe->invoked_flag |= INVOKED_SCALAR; } if (!temperature) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init temp"); if (update->whichflag == 0) { if (temperature->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) { temperature->compute_scalar(); temperature->invoked_flag |= INVOKED_SCALAR; } if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_scalar != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_SCALAR)) { pressure->compute_scalar(); @@ -1122,81 +1119,81 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"evdwl") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_evdwl(); } else if (strcmp(word,"ecoul") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_ecoul(); } else if (strcmp(word,"epair") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_epair(); } else if (strcmp(word,"ebond") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_ebond(); } else if (strcmp(word,"eangle") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_eangle(); } else if (strcmp(word,"edihed") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_edihed(); } else if (strcmp(word,"eimp") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_eimp(); } else if (strcmp(word,"emol") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_emol(); } else if (strcmp(word,"elong") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_elong(); } else if (strcmp(word,"etail") == 0) { if (update->eflag_global != update->ntimestep) - error->all("Energy was not tallied on needed timestep"); + error->all(FLERR,"Energy was not tallied on needed timestep"); if (!pe) - error->all("Thermo keyword in variable requires thermo to use/init pe"); + error->all(FLERR,"Thermo keyword in variable requires thermo to use/init pe"); pe->invoked_flag |= INVOKED_SCALAR; compute_etail(); @@ -1218,24 +1215,24 @@ int Thermo::evaluate_keyword(char *word, double *answer) else if (strcmp(word,"xlat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword in variable requires lattice be defined"); + error->all(FLERR,"Thermo keyword in variable requires lattice be defined"); compute_xlat(); } else if (strcmp(word,"ylat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword in variable requires lattice be defined"); + error->all(FLERR,"Thermo keyword in variable requires lattice be defined"); compute_ylat(); } else if (strcmp(word,"zlat") == 0) { if (domain->lattice == NULL) - error->all("Thermo keyword in variable requires lattice be defined"); + error->all(FLERR,"Thermo keyword in variable requires lattice be defined"); compute_zlat(); } else if (strcmp(word,"pxx") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); @@ -1245,11 +1242,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pyy") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); @@ -1259,11 +1256,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pzz") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); @@ -1273,11 +1270,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pxy") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); @@ -1287,11 +1284,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pxz") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); @@ -1301,11 +1298,11 @@ int Thermo::evaluate_keyword(char *word, double *answer) } else if (strcmp(word,"pyz") == 0) { if (!pressure) - error->all("Thermo keyword in variable requires " + error->all(FLERR,"Thermo keyword in variable requires " "thermo to use/init press"); if (update->whichflag == 0) { if (pressure->invoked_vector != update->ntimestep) - error->all("Compute used in variable thermo keyword between runs " + error->all(FLERR,"Compute used in variable thermo keyword between runs " "is not current"); } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) { pressure->compute_vector(); diff --git a/src/update.cpp b/src/update.cpp index 947bba8c1e..1ac25170d9 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -91,10 +91,10 @@ void Update::init() if (whichflag == 1 && lmp->cuda) if (strstr(integrate_style,"cuda") == NULL) - error->all("USER-CUDA mode requires CUDA variant of run style"); + error->all(FLERR,"USER-CUDA mode requires CUDA variant of run style"); if (whichflag == 2 && lmp->cuda) if (strstr(minimize_style,"cuda") == NULL) - error->all("USER-CUDA mode requires CUDA variant of min style"); + error->all(FLERR,"USER-CUDA mode requires CUDA variant of min style"); // init the appropriate integrate and/or minimize class // if neither (e.g. from write_restart) then just return @@ -224,7 +224,7 @@ void Update::set_units(const char *style) dt = 0.001; neighbor->skin = 2.0; - } else error->all("Illegal units command"); + } else error->all(FLERR,"Illegal units command"); delete [] unit_style; int n = strlen(style) + 1; @@ -236,7 +236,7 @@ void Update::set_units(const char *style) void Update::create_integrate(int narg, char **arg, char *suffix) { - if (narg < 1) error->all("Illegal run_style command"); + if (narg < 1) error->all(FLERR,"Illegal run_style command"); delete [] integrate_style; delete integrate; @@ -296,7 +296,7 @@ void Update::new_integrate(char *style, int narg, char **arg, #undef IntegrateStyle #undef INTEGRATE_CLASS - else error->all("Illegal integrate style"); + else error->all(FLERR,"Illegal integrate style"); } } @@ -304,7 +304,7 @@ void Update::new_integrate(char *style, int narg, char **arg, void Update::create_minimize(int narg, char **arg) { - if (narg != 1) error->all("Illegal min_style command"); + if (narg != 1) error->all(FLERR,"Illegal min_style command"); delete [] minimize_style; delete minimize; @@ -317,7 +317,7 @@ void Update::create_minimize(int narg, char **arg) #include "style_minimize.h" #undef MINIMIZE_CLASS - else error->all("Illegal min_style command"); + else error->all(FLERR,"Illegal min_style command"); int n = strlen(arg[0]) + 1; minimize_style = new char[n]; @@ -337,21 +337,21 @@ void Update::create_minimize(int narg, char **arg) void Update::reset_timestep(int narg, char **arg) { - if (narg != 1) error->all("Illegal reset_timestep command"); + if (narg != 1) error->all(FLERR,"Illegal reset_timestep command"); for (int i = 0; i < output->ndump; i++) if (output->last_dump[i] >= 0) - error->all("Cannot reset timestep with dump file already written to"); + error->all(FLERR,"Cannot reset timestep with dump file already written to"); if (output->restart && output->last_restart >= 0) - error->all("Cannot reset timestep with restart file already written"); + error->all(FLERR,"Cannot reset timestep with restart file already written"); for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->time_depend) - error->all("Cannot reset timestep with a time-dependent fix defined"); + error->all(FLERR,"Cannot reset timestep with a time-dependent fix defined"); for (int i = 0; i < domain->nregion; i++) if (domain->regions[i]->dynamic_check()) - error->all("Cannot reset timestep with a dynamic region defined"); + error->all(FLERR,"Cannot reset timestep with a dynamic region defined"); eflag_global = vflag_global = -1; @@ -367,8 +367,8 @@ void Update::reset_timestep(int narg, char **arg) if (modify->compute[i]->timeflag) modify->compute[i]->clearstep(); ntimestep = ATOBIGINT(arg[0]); - if (ntimestep < 0) error->all("Timestep must be >= 0"); - if (ntimestep > MAXBIGINT) error->all("Too big a timestep"); + if (ntimestep < 0) error->all(FLERR,"Timestep must be >= 0"); + if (ntimestep > MAXBIGINT) error->all(FLERR,"Too big a timestep"); } /* ---------------------------------------------------------------------- diff --git a/src/variable.cpp b/src/variable.cpp index b8ec5e589e..cab825ff4a 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -37,9 +37,6 @@ using namespace LAMMPS_NS; #define VARDELTA 4 #define MAXLEVEL 4 -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - #define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a) enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,EQUAL,ATOM}; @@ -122,13 +119,13 @@ Variable::~Variable() void Variable::set(int narg, char **arg) { - if (narg < 2) error->all("Illegal variable command"); + if (narg < 2) error->all(FLERR,"Illegal variable command"); // DELETE // doesn't matter if variable no longer exists if (strcmp(arg[1],"delete") == 0) { - if (narg != 2) error->all("Illegal variable command"); + if (narg != 2) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) remove(find(arg[0])); return; @@ -136,7 +133,7 @@ void Variable::set(int narg, char **arg) // num = listed args, which = 1st value, data = copied args } else if (strcmp(arg[1],"index") == 0) { - if (narg < 3) error->all("Illegal variable command"); + if (narg < 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) return; if (nvar == maxvar) extend(); style[nvar] = INDEX; @@ -158,7 +155,7 @@ void Variable::set(int narg, char **arg) if (narg == 3 || (narg == 4 && strcmp(arg[3],"pad") == 0)) { nfirst = 1; nlast = atoi(arg[2]); - if (nlast <= 0) error->all("Illegal variable command"); + if (nlast <= 0) error->all(FLERR,"Illegal variable command"); if (narg == 4 && strcmp(arg[3],"pad") == 0) { char digits[12]; sprintf(digits,"%d",nlast); @@ -167,13 +164,13 @@ void Variable::set(int narg, char **arg) } else if (narg == 4 || (narg == 5 && strcmp(arg[4],"pad") == 0)) { nfirst = atoi(arg[2]); nlast = atoi(arg[3]); - if (nfirst > nlast || nlast <= 0) error->all("Illegal variable command"); + if (nfirst > nlast || nlast <= 0) error->all(FLERR,"Illegal variable command"); if (narg == 5 && strcmp(arg[4],"pad") == 0) { char digits[12]; sprintf(digits,"%d",nlast); pad[nvar] = strlen(digits); } else pad[nvar] = 0; - } else error->all("Illegal variable command"); + } else error->all(FLERR,"Illegal variable command"); num[nvar] = nlast; which[nvar] = nfirst-1; data[nvar] = new char*[1]; @@ -184,13 +181,13 @@ void Variable::set(int narg, char **arg) // error check that num = # of worlds in universe } else if (strcmp(arg[1],"world") == 0) { - if (narg < 3) error->all("Illegal variable command"); + if (narg < 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) return; if (nvar == maxvar) extend(); style[nvar] = WORLD; num[nvar] = narg - 2; if (num[nvar] != universe->nworlds) - error->all("World variable count doesn't match # of partitions"); + error->all(FLERR,"World variable count doesn't match # of partitions"); which[nvar] = universe->iworld; pad[nvar] = 0; data[nvar] = new char*[num[nvar]]; @@ -205,7 +202,7 @@ void Variable::set(int narg, char **arg) } else if (strcmp(arg[1],"universe") == 0 || strcmp(arg[1],"uloop") == 0) { if (strcmp(arg[1],"universe") == 0) { - if (narg < 3) error->all("Illegal variable command"); + if (narg < 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) return; if (nvar == maxvar) extend(); style[nvar] = UNIVERSE; @@ -215,7 +212,7 @@ void Variable::set(int narg, char **arg) copy(num[nvar],&arg[2],data[nvar]); } else if (strcmp(arg[1],"uloop") == 0) { if (narg < 3 || narg > 4 || (narg == 4 && strcmp(arg[3],"pad") != 0)) - error->all("Illegal variable command"); + error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) return; if (nvar == maxvar) extend(); style[nvar] = ULOOP; @@ -230,7 +227,7 @@ void Variable::set(int narg, char **arg) } if (num[nvar] < universe->nworlds) - error->all("Universe/uloop variable count < # of partitions"); + error->all(FLERR,"Universe/uloop variable count < # of partitions"); which[nvar] = universe->iworld; if (universe->me == 0) { @@ -242,7 +239,7 @@ void Variable::set(int narg, char **arg) for (int jvar = 0; jvar < nvar; jvar++) if (num[jvar] && (style[jvar] == UNIVERSE || style[jvar] == ULOOP) && num[nvar] != num[jvar]) - error->all("All universe/uloop variables must have same # of values"); + error->all(FLERR,"All universe/uloop variables must have same # of values"); // STRING // remove pre-existing var if also style STRING (allows it to be reset) @@ -250,10 +247,10 @@ void Variable::set(int narg, char **arg) // data = 1 value, string to eval } else if (strcmp(arg[1],"string") == 0) { - if (narg != 3) error->all("Illegal variable command"); + if (narg != 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) { if (style[find(arg[0])] != STRING) - error->all("Cannot redefine variable as a different style"); + error->all(FLERR,"Cannot redefine variable as a different style"); remove(find(arg[0])); } if (nvar == maxvar) extend(); @@ -270,10 +267,10 @@ void Variable::set(int narg, char **arg) // data = 2 values, 1st is string to eval, 2nd is filled on retrieval } else if (strcmp(arg[1],"equal") == 0) { - if (narg != 3) error->all("Illegal variable command"); + if (narg != 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) { if (style[find(arg[0])] != EQUAL) - error->all("Cannot redefine variable as a different style"); + error->all(FLERR,"Cannot redefine variable as a different style"); remove(find(arg[0])); } if (nvar == maxvar) extend(); @@ -291,10 +288,10 @@ void Variable::set(int narg, char **arg) // data = 1 value, string to eval } else if (strcmp(arg[1],"atom") == 0) { - if (narg != 3) error->all("Illegal variable command"); + if (narg != 3) error->all(FLERR,"Illegal variable command"); if (find(arg[0]) >= 0) { if (style[find(arg[0])] != ATOM) - error->all("Cannot redefine variable as a different style"); + error->all(FLERR,"Cannot redefine variable as a different style"); remove(find(arg[0])); } if (nvar == maxvar) extend(); @@ -305,7 +302,7 @@ void Variable::set(int narg, char **arg) data[nvar] = new char*[num[nvar]]; copy(1,&arg[2],data[nvar]); - } else error->all("Illegal variable command"); + } else error->all(FLERR,"Illegal variable command"); // set name of variable // must come at end, since STRING/EQUAL/ATOM reset may have removed name @@ -317,7 +314,7 @@ void Variable::set(int narg, char **arg) for (int i = 0; i < n-1; i++) if (!isalnum(names[nvar][i]) && names[nvar][i] != '_') - error->all("Variable name must be alphanumeric or " + error->all(FLERR,"Variable name must be alphanumeric or " "underscore characters"); nvar++; } @@ -347,25 +344,25 @@ int Variable::next(int narg, char **arg) { int ivar; - if (narg == 0) error->all("Illegal next command"); + if (narg == 0) error->all(FLERR,"Illegal next command"); // check that variables exist and are all the same style // exception: UNIVERSE and ULOOP variables can be mixed in same next command for (int iarg = 0; iarg < narg; iarg++) { ivar = find(arg[iarg]); - if (ivar == -1) error->all("Invalid variable in next command"); + if (ivar == -1) error->all(FLERR,"Invalid variable in next command"); if (style[ivar] == ULOOP && style[find(arg[0])] == UNIVERSE) continue; else if (style[ivar] == UNIVERSE && style[find(arg[0])] == ULOOP) continue; else if (style[ivar] != style[find(arg[0])]) - error->all("All variables in next command must be same style"); + error->all(FLERR,"All variables in next command must be same style"); } // invalid styles STRING or EQUAL or WORLD or ATOM int istyle = style[find(arg[0])]; if (istyle == STRING || istyle == EQUAL || istyle == WORLD || istyle == ATOM) - error->all("Invalid variable style with next command"); + error->all(FLERR,"Invalid variable style with next command"); // increment all variables in list // if any variable is exhausted, set flag = 1 and remove var to allow re-use @@ -655,7 +652,7 @@ double Variable::evaluate(char *str, Tree **tree) // ---------------- else if (onechar == '(') { - if (expect == OP) error->all("Invalid syntax in variable formula"); + if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula"); expect = OP; char *contents; @@ -677,7 +674,7 @@ double Variable::evaluate(char *str, Tree **tree) // ---------------- } else if (isdigit(onechar) || onechar == '.') { - if (expect == OP) error->all("Invalid syntax in variable formula"); + if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula"); expect = OP; // istop = end of number, including scientific notation @@ -712,7 +709,7 @@ double Variable::evaluate(char *str, Tree **tree) // ---------------- } else if (isalpha(onechar)) { - if (expect == OP) error->all("Invalid syntax in variable formula"); + if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula"); expect = OP; // istop = end of word @@ -733,14 +730,14 @@ double Variable::evaluate(char *str, Tree **tree) if (strncmp(word,"c_",2) == 0) { if (domain->box_exist == 0) - error->all("Variable evaluation before simulation box is defined"); + error->all(FLERR,"Variable evaluation before simulation box is defined"); n = strlen(word) - 2 + 1; char *id = new char[n]; strcpy(id,&word[2]); int icompute = modify->find_compute(id); - if (icompute < 0) error->all("Invalid compute ID in variable formula"); + if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula"); Compute *compute = modify->compute[icompute]; delete [] id; @@ -770,7 +767,7 @@ double Variable::evaluate(char *str, Tree **tree) if (update->whichflag == 0) { if (compute->invoked_scalar != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_SCALAR)) { compute->compute_scalar(); @@ -791,11 +788,11 @@ double Variable::evaluate(char *str, Tree **tree) } else if (nbracket == 1 && compute->vector_flag) { if (index1 > compute->size_vector) - error->all("Variable formula compute vector " + error->all(FLERR,"Variable formula compute vector " "is accessed out-of-range"); if (update->whichflag == 0) { if (compute->invoked_vector != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_VECTOR)) { compute->compute_vector(); @@ -816,14 +813,14 @@ double Variable::evaluate(char *str, Tree **tree) } else if (nbracket == 2 && compute->array_flag) { if (index1 > compute->size_array_rows) - error->all("Variable formula compute array " + error->all(FLERR,"Variable formula compute array " "is accessed out-of-range"); if (index2 > compute->size_array_cols) - error->all("Variable formula compute array " + error->all(FLERR,"Variable formula compute array " "is accessed out-of-range"); if (update->whichflag == 0) { if (compute->invoked_array != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_ARRAY)) { compute->compute_array(); @@ -846,7 +843,7 @@ double Variable::evaluate(char *str, Tree **tree) if (update->whichflag == 0) { if (compute->invoked_peratom != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_PERATOM)) { compute->compute_peratom(); @@ -862,11 +859,11 @@ double Variable::evaluate(char *str, Tree **tree) compute->size_peratom_cols > 0) { if (index2 > compute->size_peratom_cols) - error->all("Variable formula compute array " + error->all(FLERR,"Variable formula compute array " "is accessed out-of-range"); if (update->whichflag == 0) { if (compute->invoked_peratom != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_PERATOM)) { compute->compute_peratom(); @@ -883,10 +880,10 @@ double Variable::evaluate(char *str, Tree **tree) compute->size_peratom_cols == 0) { if (tree == NULL) - error->all("Per-atom compute in equal-style variable formula"); + error->all(FLERR,"Per-atom compute in equal-style variable formula"); if (update->whichflag == 0) { if (compute->invoked_peratom != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_PERATOM)) { compute->compute_peratom(); @@ -906,13 +903,13 @@ double Variable::evaluate(char *str, Tree **tree) compute->size_peratom_cols > 0) { if (tree == NULL) - error->all("Per-atom compute in equal-style variable formula"); + error->all(FLERR,"Per-atom compute in equal-style variable formula"); if (index1 > compute->size_peratom_cols) - error->all("Variable formula compute array " + error->all(FLERR,"Variable formula compute array " "is accessed out-of-range"); if (update->whichflag == 0) { if (compute->invoked_peratom != update->ntimestep) - error->all("Compute used in variable between runs " + error->all(FLERR,"Compute used in variable between runs " "is not current"); } else if (!(compute->invoked_flag & INVOKED_PERATOM)) { compute->compute_peratom(); @@ -926,7 +923,7 @@ double Variable::evaluate(char *str, Tree **tree) newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; - } else error->all("Mismatched compute in variable formula"); + } else error->all(FLERR,"Mismatched compute in variable formula"); // ---------------- // fix @@ -934,14 +931,14 @@ double Variable::evaluate(char *str, Tree **tree) } else if (strncmp(word,"f_",2) == 0) { if (domain->box_exist == 0) - error->all("Variable evaluation before simulation box is defined"); + error->all(FLERR,"Variable evaluation before simulation box is defined"); n = strlen(word) - 2 + 1; char *id = new char[n]; strcpy(id,&word[2]); int ifix = modify->find_fix(id); - if (ifix < 0) error->all("Invalid fix ID in variable formula"); + if (ifix < 0) error->all(FLERR,"Invalid fix ID in variable formula"); Fix *fix = modify->fix[ifix]; delete [] id; @@ -970,7 +967,7 @@ double Variable::evaluate(char *str, Tree **tree) if (nbracket == 0 && fix->scalar_flag) { if (update->whichflag > 0 && update->ntimestep % fix->global_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); value1 = fix->compute_scalar(); if (tree) { @@ -986,9 +983,9 @@ double Variable::evaluate(char *str, Tree **tree) } else if (nbracket == 1 && fix->vector_flag) { if (index1 > fix->size_vector) - error->all("Variable formula fix vector is accessed out-of-range"); + error->all(FLERR,"Variable formula fix vector is accessed out-of-range"); if (update->whichflag > 0 && update->ntimestep % fix->global_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); value1 = fix->compute_vector(index1-1); if (tree) { @@ -1004,11 +1001,11 @@ double Variable::evaluate(char *str, Tree **tree) } else if (nbracket == 2 && fix->array_flag) { if (index1 > fix->size_array_rows) - error->all("Variable formula fix array is accessed out-of-range"); + error->all(FLERR,"Variable formula fix array is accessed out-of-range"); if (index2 > fix->size_array_cols) - error->all("Variable formula fix array is accessed out-of-range"); + error->all(FLERR,"Variable formula fix array is accessed out-of-range"); if (update->whichflag > 0 && update->ntimestep % fix->global_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); value1 = fix->compute_array(index1-1,index2-1); if (tree) { @@ -1026,7 +1023,7 @@ double Variable::evaluate(char *str, Tree **tree) if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); peratom2global(1,NULL,fix->vector_atom,1,index1, tree,treestack,ntreestack,argstack,nargstack); @@ -1037,10 +1034,10 @@ double Variable::evaluate(char *str, Tree **tree) fix->size_peratom_cols > 0) { if (index2 > fix->size_peratom_cols) - error->all("Variable formula fix array is accessed out-of-range"); + error->all(FLERR,"Variable formula fix array is accessed out-of-range"); if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); peratom2global(1,NULL,&fix->array_atom[0][index2-1], fix->size_peratom_cols,index1, @@ -1052,10 +1049,10 @@ double Variable::evaluate(char *str, Tree **tree) fix->size_peratom_cols == 0) { if (tree == NULL) - error->all("Per-atom fix in equal-style variable formula"); + error->all(FLERR,"Per-atom fix in equal-style variable formula"); if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); Tree *newtree = new Tree(); newtree->type = ATOMARRAY; @@ -1070,12 +1067,12 @@ double Variable::evaluate(char *str, Tree **tree) fix->size_peratom_cols > 0) { if (tree == NULL) - error->all("Per-atom fix in equal-style variable formula"); + error->all(FLERR,"Per-atom fix in equal-style variable formula"); if (index1 > fix->size_peratom_cols) - error->all("Variable formula fix array is accessed out-of-range"); + error->all(FLERR,"Variable formula fix array is accessed out-of-range"); if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); Tree *newtree = new Tree(); newtree->type = ATOMARRAY; @@ -1085,7 +1082,7 @@ double Variable::evaluate(char *str, Tree **tree) treestack[ntreestack++] = newtree; - } else error->all("Mismatched fix in variable formula"); + } else error->all(FLERR,"Mismatched fix in variable formula"); // ---------------- // variable @@ -1097,7 +1094,7 @@ double Variable::evaluate(char *str, Tree **tree) strcpy(id,&word[2]); int ivar = find(id); - if (ivar < 0) error->all("Invalid variable name in variable formula"); + if (ivar < 0) error->all(FLERR,"Invalid variable name in variable formula"); // parse zero or one trailing brackets // point i beyond last bracket @@ -1119,7 +1116,7 @@ double Variable::evaluate(char *str, Tree **tree) char *var = retrieve(id); if (var == NULL) - error->all("Invalid variable evaluation in variable formula"); + error->all(FLERR,"Invalid variable evaluation in variable formula"); if (tree) { Tree *newtree = new Tree(); newtree->type = VALUE; @@ -1133,7 +1130,7 @@ double Variable::evaluate(char *str, Tree **tree) } else if (nbracket == 0 && style[ivar] == ATOM) { if (tree == NULL) - error->all("Atom-style variable in equal-style variable formula"); + error->all(FLERR,"Atom-style variable in equal-style variable formula"); Tree *newtree; evaluate(data[ivar][0],&newtree); treestack[ntreestack++] = newtree; @@ -1151,7 +1148,7 @@ double Variable::evaluate(char *str, Tree **tree) tree,treestack,ntreestack,argstack,nargstack); memory->destroy(result); - } else error->all("Mismatched variable in variable formula"); + } else error->all(FLERR,"Mismatched variable in variable formula"); delete [] id; @@ -1177,7 +1174,7 @@ double Variable::evaluate(char *str, Tree **tree) treestack,ntreestack,argstack,nargstack)); else if (special_function(word,contents,tree, treestack,ntreestack,argstack,nargstack)); - else error->all("Invalid math/group/special function " + else error->all(FLERR,"Invalid math/group/special function " "in variable formula"); delete [] contents; @@ -1187,7 +1184,7 @@ double Variable::evaluate(char *str, Tree **tree) } else if (str[i] == '[') { if (domain->box_exist == 0) - error->all("Variable evaluation before simulation box is defined"); + error->all(FLERR,"Variable evaluation before simulation box is defined"); ptr = &str[i]; int id = int_between_brackets(ptr); @@ -1202,7 +1199,7 @@ double Variable::evaluate(char *str, Tree **tree) } else if (is_atom_vector(word)) { if (domain->box_exist == 0) - error->all("Variable evaluation before simulation box is defined"); + error->all(FLERR,"Variable evaluation before simulation box is defined"); atom_vector(word,tree,treestack,ntreestack); @@ -1226,10 +1223,10 @@ double Variable::evaluate(char *str, Tree **tree) } else { if (domain->box_exist == 0) - error->all("Variable evaluation before simulation box is defined"); + error->all(FLERR,"Variable evaluation before simulation box is defined"); int flag = output->thermo->evaluate_keyword(word,&value1); - if (flag) error->all("Invalid thermo keyword in variable formula"); + if (flag) error->all(FLERR,"Invalid thermo keyword in variable formula"); if (tree) { Tree *newtree = new Tree(); newtree->type = VALUE; @@ -1253,7 +1250,7 @@ double Variable::evaluate(char *str, Tree **tree) else if (onechar == '/') op = DIVIDE; else if (onechar == '^') op = CARAT; else if (onechar == '=') { - if (str[i+1] != '=') error->all("Invalid syntax in variable formula"); + if (str[i+1] != '=') error->all(FLERR,"Invalid syntax in variable formula"); op = EQ; i++; } else if (onechar == '!') { @@ -1274,11 +1271,11 @@ double Variable::evaluate(char *str, Tree **tree) i++; } } else if (onechar == '&') { - if (str[i+1] != '&') error->all("Invalid syntax in variable formula"); + if (str[i+1] != '&') error->all(FLERR,"Invalid syntax in variable formula"); op = AND; i++; } else if (onechar == '|') { - if (str[i+1] != '|') error->all("Invalid syntax in variable formula"); + if (str[i+1] != '|') error->all(FLERR,"Invalid syntax in variable formula"); op = OR; i++; } else op = DONE; @@ -1294,7 +1291,7 @@ double Variable::evaluate(char *str, Tree **tree) continue; } - if (expect == ARG) error->all("Invalid syntax in variable formula"); + if (expect == ARG) error->all(FLERR,"Invalid syntax in variable formula"); expect = ARG; // evaluate stack as deep as possible while respecting precedence @@ -1328,10 +1325,10 @@ double Variable::evaluate(char *str, Tree **tree) else if (opprevious == MULTIPLY) argstack[nargstack++] = value1 * value2; else if (opprevious == DIVIDE) { - if (value2 == 0.0) error->all("Divide by 0 in variable formula"); + if (value2 == 0.0) error->all(FLERR,"Divide by 0 in variable formula"); argstack[nargstack++] = value1 / value2; } else if (opprevious == CARAT) { - if (value2 == 0.0) error->all("Power by 0 in variable formula"); + if (value2 == 0.0) error->all(FLERR,"Power by 0 in variable formula"); argstack[nargstack++] = pow(value1,value2); } else if (opprevious == UNARY) { argstack[nargstack++] = -value2; @@ -1374,20 +1371,20 @@ double Variable::evaluate(char *str, Tree **tree) opstack[nopstack++] = op; - } else error->all("Invalid syntax in variable formula"); + } else error->all(FLERR,"Invalid syntax in variable formula"); } - if (nopstack) error->all("Invalid syntax in variable formula"); + if (nopstack) error->all(FLERR,"Invalid syntax in variable formula"); // for atom-style variable, return remaining tree // for equal-style variable, return remaining arg if (tree) { - if (ntreestack != 1) error->all("Invalid syntax in variable formula"); + if (ntreestack != 1) error->all(FLERR,"Invalid syntax in variable formula"); *tree = treestack[0]; return 0.0; } else { - if (nargstack != 1) error->all("Invalid syntax in variable formula"); + if (nargstack != 1) error->all(FLERR,"Invalid syntax in variable formula"); return argstack[0]; } } @@ -1447,7 +1444,7 @@ double Variable::collapse_tree(Tree *tree) arg2 = collapse_tree(tree->right); if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0; tree->type = VALUE; - if (arg2 == 0.0) error->one("Divide by 0 in variable formula"); + if (arg2 == 0.0) error->one(FLERR,"Divide by 0 in variable formula"); tree->value = arg1 / arg2; return tree->value; } @@ -1457,7 +1454,7 @@ double Variable::collapse_tree(Tree *tree) arg2 = collapse_tree(tree->right); if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0; tree->type = VALUE; - if (arg2 == 0.0) error->one("Power by 0 in variable formula"); + if (arg2 == 0.0) error->one(FLERR,"Power by 0 in variable formula"); tree->value = pow(arg1,arg2); return tree->value; } @@ -1563,7 +1560,7 @@ double Variable::collapse_tree(Tree *tree) arg1 = collapse_tree(tree->left); if (tree->left->type != VALUE) return 0.0; tree->type = VALUE; - if (arg1 < 0.0) error->one("Sqrt of negative value in variable formula"); + if (arg1 < 0.0) error->one(FLERR,"Sqrt of negative value in variable formula"); tree->value = sqrt(arg1); return tree->value; } @@ -1581,7 +1578,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE) return 0.0; tree->type = VALUE; if (arg1 <= 0.0) - error->one("Log of zero/negative value in variable formula"); + error->one(FLERR,"Log of zero/negative value in variable formula"); tree->value = log(arg1); return tree->value; } @@ -1591,7 +1588,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE) return 0.0; tree->type = VALUE; if (arg1 <= 0.0) - error->one("Log of zero/negative value in variable formula"); + error->one(FLERR,"Log of zero/negative value in variable formula"); tree->value = log10(arg1); return tree->value; } @@ -1625,7 +1622,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE) return 0.0; tree->type = VALUE; if (arg1 < -1.0 || arg1 > 1.0) - error->one("Arcsin of invalid value in variable formula"); + error->one(FLERR,"Arcsin of invalid value in variable formula"); tree->value = asin(arg1); return tree->value; } @@ -1635,7 +1632,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE) return 0.0; tree->type = VALUE; if (arg1 < -1.0 || arg1 > 1.0) - error->one("Arccos of invalid value in variable formula"); + error->one(FLERR,"Arccos of invalid value in variable formula"); tree->value = acos(arg1); return tree->value; } @@ -1664,7 +1661,7 @@ double Variable::collapse_tree(Tree *tree) collapse_tree(tree->middle); if (randomatom == NULL) { int seed = static_cast (collapse_tree(tree->right)); - if (seed <= 0) error->one("Invalid math function in variable formula"); + if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula"); randomatom = new RanMars(lmp,seed+me); } return 0.0; @@ -1673,10 +1670,10 @@ double Variable::collapse_tree(Tree *tree) if (tree->type == NORMAL) { collapse_tree(tree->left); double sigma = collapse_tree(tree->middle); - if (sigma < 0.0) error->one("Invalid math function in variable formula"); + if (sigma < 0.0) error->one(FLERR,"Invalid math function in variable formula"); if (randomatom == NULL) { int seed = static_cast (collapse_tree(tree->right)); - if (seed <= 0) error->one("Invalid math function in variable formula"); + if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula"); randomatom = new RanMars(lmp,seed+me); } return 0.0; @@ -1723,7 +1720,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0; tree->type = VALUE; if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2) - error->one("Invalid math function in variable formula"); + error->one(FLERR,"Invalid math function in variable formula"); int lower = update->ntimestep/ivalue1 * ivalue1; int delta = update->ntimestep - lower; if (delta < ivalue2) tree->value = lower+ivalue2; @@ -1739,7 +1736,7 @@ double Variable::collapse_tree(Tree *tree) tree->right->type != VALUE) return 0.0; tree->type = VALUE; if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3) - error->one("Invalid math function in variable formula"); + error->one(FLERR,"Invalid math function in variable formula"); if (update->ntimestep < ivalue1) tree->value = ivalue1; else { int lower = ivalue1; @@ -1768,7 +1765,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE || tree->middle->type != VALUE || tree->right->type != VALUE) return 0.0; tree->type = VALUE; - if (arg3 == 0.0) error->one("Invalid math function in variable formula"); + if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/arg3; tree->value = arg1 + arg2*sin(omega*delta*update->dt); @@ -1782,7 +1779,7 @@ double Variable::collapse_tree(Tree *tree) if (tree->left->type != VALUE || tree->middle->type != VALUE || tree->right->type != VALUE) return 0.0; tree->type = VALUE; - if (arg3 == 0.0) error->one("Invalid math function in variable formula"); + if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/arg3; tree->value = arg1 + arg2*(1.0-cos(omega*delta*update->dt)); @@ -1826,12 +1823,12 @@ double Variable::eval_tree(Tree *tree, int i) return eval_tree(tree->left,i) * eval_tree(tree->right,i); if (tree->type == DIVIDE) { double denom = eval_tree(tree->right,i); - if (denom == 0.0) error->one("Divide by 0 in variable formula"); + if (denom == 0.0) error->one(FLERR,"Divide by 0 in variable formula"); return eval_tree(tree->left,i) / denom; } if (tree->type == CARAT) { double exponent = eval_tree(tree->right,i); - if (exponent == 0.0) error->one("Power by 0 in variable formula"); + if (exponent == 0.0) error->one(FLERR,"Power by 0 in variable formula"); return pow(eval_tree(tree->left,i),exponent); } if (tree->type == UNARY) return -eval_tree(tree->left,i); @@ -1877,7 +1874,7 @@ double Variable::eval_tree(Tree *tree, int i) if (tree->type == SQRT) { arg1 = eval_tree(tree->left,i); - if (arg1 < 0.0) error->one("Sqrt of negative value in variable formula"); + if (arg1 < 0.0) error->one(FLERR,"Sqrt of negative value in variable formula"); return sqrt(arg1); } if (tree->type == EXP) @@ -1885,13 +1882,13 @@ double Variable::eval_tree(Tree *tree, int i) if (tree->type == LN) { arg1 = eval_tree(tree->left,i); if (arg1 <= 0.0) - error->one("Log of zero/negative value in variable formula"); + error->one(FLERR,"Log of zero/negative value in variable formula"); return log(arg1); } if (tree->type == LOG) { arg1 = eval_tree(tree->left,i); if (arg1 <= 0.0) - error->one("Log of zero/negative value in variable formula"); + error->one(FLERR,"Log of zero/negative value in variable formula"); return log10(arg1); } @@ -1905,13 +1902,13 @@ double Variable::eval_tree(Tree *tree, int i) if (tree->type == ASIN) { arg1 = eval_tree(tree->left,i); if (arg1 < -1.0 || arg1 > 1.0) - error->one("Arcsin of invalid value in variable formula"); + error->one(FLERR,"Arcsin of invalid value in variable formula"); return asin(arg1); } if (tree->type == ACOS) { arg1 = eval_tree(tree->left,i); if (arg1 < -1.0 || arg1 > 1.0) - error->one("Arccos of invalid value in variable formula"); + error->one(FLERR,"Arccos of invalid value in variable formula"); return acos(arg1); } if (tree->type == ATAN) @@ -1924,7 +1921,7 @@ double Variable::eval_tree(Tree *tree, int i) double upper = eval_tree(tree->middle,i); if (randomatom == NULL) { int seed = static_cast (eval_tree(tree->right,i)); - if (seed <= 0) error->one("Invalid math function in variable formula"); + if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula"); randomatom = new RanMars(lmp,seed+me); } return randomatom->uniform()*(upper-lower)+lower; @@ -1932,10 +1929,10 @@ double Variable::eval_tree(Tree *tree, int i) if (tree->type == NORMAL) { double mu = eval_tree(tree->left,i); double sigma = eval_tree(tree->middle,i); - if (sigma < 0.0) error->one("Invalid math function in variable formula"); + if (sigma < 0.0) error->one(FLERR,"Invalid math function in variable formula"); if (randomatom == NULL) { int seed = static_cast (eval_tree(tree->right,i)); - if (seed <= 0) error->one("Invalid math function in variable formula"); + if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula"); randomatom = new RanMars(lmp,seed+me); } return mu + sigma*randomatom->gaussian(); @@ -1961,7 +1958,7 @@ double Variable::eval_tree(Tree *tree, int i) int ivalue1 = static_cast (eval_tree(tree->left,i)); int ivalue2 = static_cast (eval_tree(tree->right,i)); if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2) - error->one("Invalid math function in variable formula"); + error->one(FLERR,"Invalid math function in variable formula"); int lower = update->ntimestep/ivalue1 * ivalue1; int delta = update->ntimestep - lower; if (delta < ivalue2) arg = lower+ivalue2; @@ -1974,7 +1971,7 @@ double Variable::eval_tree(Tree *tree, int i) int ivalue2 = static_cast (eval_tree(tree->middle,i)); int ivalue3 = static_cast (eval_tree(tree->right,i)); if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3) - error->one("Invalid math function in variable formula"); + error->one(FLERR,"Invalid math function in variable formula"); if (update->ntimestep < ivalue1) arg = ivalue1; else { int lower = ivalue1; @@ -1998,7 +1995,7 @@ double Variable::eval_tree(Tree *tree, int i) arg1 = eval_tree(tree->left,i); arg2 = eval_tree(tree->middle,i); arg3 = eval_tree(tree->right,i); - if (arg3 == 0.0) error->one("Invalid math function in variable formula"); + if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/arg3; arg = arg1 + arg2*sin(omega*delta*update->dt); @@ -2009,7 +2006,7 @@ double Variable::eval_tree(Tree *tree, int i) arg1 = eval_tree(tree->left,i); arg2 = eval_tree(tree->middle,i); arg3 = eval_tree(tree->right,i); - if (arg3 == 0.0) error->one("Invalid math function in variable formula"); + if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/arg3; arg = arg1 + arg2*(1.0-cos(omega*delta*update->dt)); @@ -2068,7 +2065,7 @@ int Variable::find_matching_paren(char *str, int i,char *&contents) else if (str[i] == ')' && ilevel) ilevel--; else if (str[i] == ')') break; } - if (!str[i]) error->all("Invalid syntax in variable formula"); + if (!str[i]) error->all(FLERR,"Invalid syntax in variable formula"); int istop = i; int n = istop - istart - 1; @@ -2093,19 +2090,19 @@ int Variable::int_between_brackets(char *&ptr) while (*ptr && *ptr != ']') { if (!isdigit(*ptr)) - error->all("Non digit character between brackets in variable"); + error->all(FLERR,"Non digit character between brackets in variable"); ptr++; } - if (*ptr != ']') error->all("Mismatched brackets in variable"); - if (ptr == start) error->all("Empty brackets in variable"); + if (*ptr != ']') error->all(FLERR,"Mismatched brackets in variable"); + if (ptr == start) error->all(FLERR,"Empty brackets in variable"); *ptr = '\0'; int index = atoi(start); *ptr = ']'; if (index == 0) - error->all("Index between variable brackets must be positive"); + error->all(FLERR,"Index between variable brackets must be positive"); return index; } @@ -2212,117 +2209,117 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } if (strcmp(word,"sqrt") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = SQRT; else { if (value1 < 0.0) - error->all("Sqrt of negative value in variable formula"); + error->all(FLERR,"Sqrt of negative value in variable formula"); argstack[nargstack++] = sqrt(value1); } } else if (strcmp(word,"exp") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = EXP; else argstack[nargstack++] = exp(value1); } else if (strcmp(word,"ln") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = LN; else { if (value1 <= 0.0) - error->all("Log of zero/negative value in variable formula"); + error->all(FLERR,"Log of zero/negative value in variable formula"); argstack[nargstack++] = log(value1); } } else if (strcmp(word,"log") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = LOG; else { if (value1 <= 0.0) - error->all("Log of zero/negative value in variable formula"); + error->all(FLERR,"Log of zero/negative value in variable formula"); argstack[nargstack++] = log10(value1); } } else if (strcmp(word,"sin") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = SIN; else argstack[nargstack++] = sin(value1); } else if (strcmp(word,"cos") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = COS; else argstack[nargstack++] = cos(value1); } else if (strcmp(word,"tan") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = TAN; else argstack[nargstack++] = tan(value1); } else if (strcmp(word,"asin") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = ASIN; else { if (value1 < -1.0 || value1 > 1.0) - error->all("Arcsin of invalid value in variable formula"); + error->all(FLERR,"Arcsin of invalid value in variable formula"); argstack[nargstack++] = asin(value1); } } else if (strcmp(word,"acos") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = ACOS; else { if (value1 < -1.0 || value1 > 1.0) - error->all("Arccos of invalid value in variable formula"); + error->all(FLERR,"Arccos of invalid value in variable formula"); argstack[nargstack++] = acos(value1); } } else if (strcmp(word,"atan") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = ATAN; else argstack[nargstack++] = atan(value1); } else if (strcmp(word,"atan2") == 0) { - if (narg != 2) error->all("Invalid math function in variable formula"); + if (narg != 2) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = ATAN2; else argstack[nargstack++] = atan2(value1,value2); } else if (strcmp(word,"random") == 0) { - if (narg != 3) error->all("Invalid math function in variable formula"); + if (narg != 3) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = RANDOM; else { if (randomequal == NULL) { int seed = static_cast (value3); - if (seed <= 0) error->all("Invalid math function in variable formula"); + if (seed <= 0) error->all(FLERR,"Invalid math function in variable formula"); randomequal = new RanMars(lmp,seed); } argstack[nargstack++] = randomequal->uniform()*(value2-value1) + value1; } } else if (strcmp(word,"normal") == 0) { - if (narg != 3) error->all("Invalid math function in variable formula"); + if (narg != 3) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = NORMAL; else { if (value2 < 0.0) - error->all("Invalid math function in variable formula"); + error->all(FLERR,"Invalid math function in variable formula"); if (randomequal == NULL) { int seed = static_cast (value3); - if (seed <= 0) error->all("Invalid math function in variable formula"); + if (seed <= 0) error->all(FLERR,"Invalid math function in variable formula"); randomequal = new RanMars(lmp,seed); } argstack[nargstack++] = value1 + value2*randomequal->gaussian(); } } else if (strcmp(word,"ceil") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = CEIL; else argstack[nargstack++] = ceil(value1); } else if (strcmp(word,"floor") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = FLOOR; else argstack[nargstack++] = floor(value1); } else if (strcmp(word,"round") == 0) { - if (narg != 1) error->all("Invalid math function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = ROUND; else argstack[nargstack++] = MYROUND(value1); } else if (strcmp(word,"ramp") == 0) { - if (narg != 2) error->all("Invalid math function in variable formula"); + if (narg != 2) error->all(FLERR,"Invalid math function in variable formula"); if (update->whichflag == 0) - error->all("Cannot use ramp in variable formula between runs"); + error->all(FLERR,"Cannot use ramp in variable formula between runs"); if (tree) newtree->type = RAMP; else { double delta = update->ntimestep - update->beginstep; @@ -2332,13 +2329,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"stagger") == 0) { - if (narg != 2) error->all("Invalid math function in variable formula"); + if (narg != 2) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = STAGGER; else { int ivalue1 = static_cast (value1); int ivalue2 = static_cast (value2); if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2) - error->all("Invalid math function in variable formula"); + error->all(FLERR,"Invalid math function in variable formula"); int lower = update->ntimestep/ivalue1 * ivalue1; int delta = update->ntimestep - lower; double value; @@ -2348,14 +2345,14 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"logfreq") == 0) { - if (narg != 3) error->all("Invalid math function in variable formula"); + if (narg != 3) error->all(FLERR,"Invalid math function in variable formula"); if (tree) newtree->type = LOGFREQ; else { int ivalue1 = static_cast (value1); int ivalue2 = static_cast (value2); int ivalue3 = static_cast (value3); if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3) - error->all("Invalid math function in variable formula"); + error->all(FLERR,"Invalid math function in variable formula"); double value; if (update->ntimestep < ivalue1) value = ivalue1; else { @@ -2369,9 +2366,9 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"vdisplace") == 0) { - if (narg != 2) error->all("Invalid math function in variable formula"); + if (narg != 2) error->all(FLERR,"Invalid math function in variable formula"); if (update->whichflag == 0) - error->all("Cannot use vdisplace in variable formula between runs"); + error->all(FLERR,"Cannot use vdisplace in variable formula between runs"); if (tree) newtree->type = VDISPLACE; else { double delta = update->ntimestep - update->beginstep; @@ -2380,13 +2377,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"swiggle") == 0) { - if (narg != 3) error->all("Invalid math function in variable formula"); + if (narg != 3) error->all(FLERR,"Invalid math function in variable formula"); if (update->whichflag == 0) - error->all("Cannot use swiggle in variable formula between runs"); + error->all(FLERR,"Cannot use swiggle in variable formula between runs"); if (tree) newtree->type = CWIGGLE; else { if (value3 == 0.0) - error->all("Invalid math function in variable formula"); + error->all(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/value3; double value = value1 + value2*sin(omega*delta*update->dt); @@ -2394,13 +2391,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"cwiggle") == 0) { - if (narg != 3) error->all("Invalid math function in variable formula"); + if (narg != 3) error->all(FLERR,"Invalid math function in variable formula"); if (update->whichflag == 0) - error->all("Cannot use cwiggle in variable formula between runs"); + error->all(FLERR,"Cannot use cwiggle in variable formula between runs"); if (tree) newtree->type = CWIGGLE; else { if (value3 == 0.0) - error->all("Invalid math function in variable formula"); + error->all(FLERR,"Invalid math function in variable formula"); double delta = update->ntimestep - update->beginstep; double omega = 2.0*PI/value3; double value = value1 + value2*(1.0-cos(omega*delta*update->dt)); @@ -2477,7 +2474,7 @@ int Variable::group_function(char *word, char *contents, Tree **tree, int igroup = group->find(arg1); if (igroup == -1) - error->all("Group ID in variable formula does not exist"); + error->all(FLERR,"Group ID in variable formula does not exist"); // match word to group function @@ -2486,17 +2483,17 @@ int Variable::group_function(char *word, char *contents, Tree **tree, if (strcmp(word,"count") == 0) { if (narg == 1) value = group->count(igroup); else if (narg == 2) value = group->count(igroup,region_function(arg2)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"mass") == 0) { if (narg == 1) value = group->mass(igroup); else if (narg == 2) value = group->mass(igroup,region_function(arg2)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"charge") == 0) { if (narg == 1) value = group->charge(igroup); else if (narg == 2) value = group->charge(igroup,region_function(arg2)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"xcm") == 0) { atom->check_mass(); @@ -2508,11 +2505,11 @@ int Variable::group_function(char *word, char *contents, Tree **tree, int iregion = region_function(arg3); double masstotal = group->mass(igroup,iregion); group->xcm(igroup,masstotal,xcm,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = xcm[0]; else if (strcmp(arg2,"y") == 0) value = xcm[1]; else if (strcmp(arg2,"z") == 0) value = xcm[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"vcm") == 0) { atom->check_mass(); @@ -2524,34 +2521,34 @@ int Variable::group_function(char *word, char *contents, Tree **tree, int iregion = region_function(arg3); double masstotal = group->mass(igroup,iregion); group->vcm(igroup,masstotal,vcm,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = vcm[0]; else if (strcmp(arg2,"y") == 0) value = vcm[1]; else if (strcmp(arg2,"z") == 0) value = vcm[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"fcm") == 0) { double fcm[3]; if (narg == 2) group->fcm(igroup,fcm); else if (narg == 3) group->fcm(igroup,fcm,region_function(arg3)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = fcm[0]; else if (strcmp(arg2,"y") == 0) value = fcm[1]; else if (strcmp(arg2,"z") == 0) value = fcm[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"bound") == 0) { double minmax[6]; if (narg == 2) group->bounds(igroup,minmax); else if (narg == 3) group->bounds(igroup,minmax,region_function(arg3)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"xmin") == 0) value = minmax[0]; else if (strcmp(arg2,"xmax") == 0) value = minmax[1]; else if (strcmp(arg2,"ymin") == 0) value = minmax[2]; else if (strcmp(arg2,"ymax") == 0) value = minmax[3]; else if (strcmp(arg2,"zmin") == 0) value = minmax[4]; else if (strcmp(arg2,"zmax") == 0) value = minmax[5]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"gyration") == 0) { atom->check_mass(); @@ -2565,12 +2562,12 @@ int Variable::group_function(char *word, char *contents, Tree **tree, double masstotal = group->mass(igroup,iregion); group->xcm(igroup,masstotal,xcm,iregion); value = group->gyration(igroup,masstotal,xcm,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"ke") == 0) { if (narg == 1) value = group->ke(igroup); else if (narg == 2) value = group->ke(igroup,region_function(arg2)); - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"angmom") == 0) { atom->check_mass(); @@ -2584,11 +2581,11 @@ int Variable::group_function(char *word, char *contents, Tree **tree, double masstotal = group->mass(igroup,iregion); group->xcm(igroup,masstotal,xcm,iregion); group->angmom(igroup,xcm,lmom,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = lmom[0]; else if (strcmp(arg2,"y") == 0) value = lmom[1]; else if (strcmp(arg2,"z") == 0) value = lmom[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"torque") == 0) { atom->check_mass(); @@ -2602,11 +2599,11 @@ int Variable::group_function(char *word, char *contents, Tree **tree, double masstotal = group->mass(igroup,iregion); group->xcm(igroup,masstotal,xcm,iregion); group->torque(igroup,xcm,tq,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = tq[0]; else if (strcmp(arg2,"y") == 0) value = tq[1]; else if (strcmp(arg2,"z") == 0) value = tq[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"inertia") == 0) { atom->check_mass(); @@ -2620,14 +2617,14 @@ int Variable::group_function(char *word, char *contents, Tree **tree, double masstotal = group->mass(igroup,iregion); group->xcm(igroup,masstotal,xcm,iregion); group->inertia(igroup,xcm,inertia,iregion); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"xx") == 0) value = inertia[0][0]; else if (strcmp(arg2,"yy") == 0) value = inertia[1][1]; else if (strcmp(arg2,"zz") == 0) value = inertia[2][2]; else if (strcmp(arg2,"xy") == 0) value = inertia[0][1]; else if (strcmp(arg2,"yz") == 0) value = inertia[1][2]; else if (strcmp(arg2,"xz") == 0) value = inertia[0][2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } else if (strcmp(word,"omega") == 0) { atom->check_mass(); @@ -2645,11 +2642,11 @@ int Variable::group_function(char *word, char *contents, Tree **tree, group->angmom(igroup,xcm,angmom,iregion); group->inertia(igroup,xcm,inertia,iregion); group->omega(angmom,inertia,omega); - } else error->all("Invalid group function in variable formula"); + } else error->all(FLERR,"Invalid group function in variable formula"); if (strcmp(arg2,"x") == 0) value = omega[0]; else if (strcmp(arg2,"y") == 0) value = omega[1]; else if (strcmp(arg2,"z") == 0) value = omega[2]; - else error->all("Invalid group function in variable formula"); + else error->all(FLERR,"Invalid group function in variable formula"); } delete [] arg1; @@ -2675,7 +2672,7 @@ int Variable::region_function(char *id) { int iregion = domain->find_region(id); if (iregion == -1) - error->all("Region ID in variable formula does not exist"); + error->all(FLERR,"Region ID in variable formula does not exist"); return iregion; } @@ -2743,7 +2740,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, else if (strcmp(word,"ave") == 0) method = AVE; else if (strcmp(word,"trap") == 0) method = TRAP; - if (narg != 1) error->all("Invalid special function in variable formula"); + if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); Compute *compute = NULL; Fix *fix = NULL; @@ -2758,12 +2755,12 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else index = 0; int icompute = modify->find_compute(&arg1[2]); - if (icompute < 0) error->all("Invalid compute ID in variable formula"); + if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula"); compute = modify->compute[icompute]; if (index == 0 && compute->vector_flag) { if (update->whichflag == 0) { if (compute->invoked_vector != update->ntimestep) - error->all("Compute used in variable between runs is not current"); + error->all(FLERR,"Compute used in variable between runs is not current"); } else if (!(compute->invoked_flag & INVOKED_VECTOR)) { compute->compute_vector(); compute->invoked_flag |= INVOKED_VECTOR; @@ -2772,18 +2769,18 @@ int Variable::special_function(char *word, char *contents, Tree **tree, nstride = 1; } else if (index && compute->array_flag) { if (index > compute->size_array_cols) - error->all("Variable formula compute array " + error->all(FLERR,"Variable formula compute array " "is accessed out-of-range"); if (update->whichflag == 0) { if (compute->invoked_array != update->ntimestep) - error->all("Compute used in variable between runs is not current"); + error->all(FLERR,"Compute used in variable between runs is not current"); } else if (!(compute->invoked_flag & INVOKED_ARRAY)) { compute->compute_array(); compute->invoked_flag |= INVOKED_ARRAY; } nvec = compute->size_array_rows; nstride = compute->size_array_cols; - } else error->all("Mismatched compute in variable formula"); + } else error->all(FLERR,"Mismatched compute in variable formula"); } else if (strstr(arg1,"f_") == arg1) { ptr1 = strchr(arg1,'['); @@ -2794,23 +2791,23 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else index = 0; int ifix = modify->find_fix(&arg1[2]); - if (ifix < 0) error->all("Invalid fix ID in variable formula"); + if (ifix < 0) error->all(FLERR,"Invalid fix ID in variable formula"); fix = modify->fix[ifix]; if (index == 0 && fix->vector_flag) { if (update->whichflag > 0 && update->ntimestep % fix->global_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); nvec = fix->size_vector; nstride = 1; } else if (index && fix->array_flag) { if (index > fix->size_array_cols) - error->all("Variable formula fix array is accessed out-of-range"); + error->all(FLERR,"Variable formula fix array is accessed out-of-range"); if (update->whichflag > 0 && update->ntimestep % fix->global_freq) - error->all("Fix in variable not computed at compatible time"); + error->all(FLERR,"Fix in variable not computed at compatible time"); nvec = fix->size_array_rows; nstride = fix->size_array_cols; - } else error->all("Mismatched fix in variable formula"); + } else error->all(FLERR,"Mismatched fix in variable formula"); - } else error->all("Invalid special function in variable formula"); + } else error->all(FLERR,"Invalid special function in variable formula"); double value = 0.0; if (method == XMIN) value = BIG; @@ -2871,12 +2868,12 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"gmask") == 0) { if (tree == NULL) - error->all("Gmask function in equal-style variable formula"); - if (narg != 1) error->all("Invalid special function in variable formula"); + error->all(FLERR,"Gmask function in equal-style variable formula"); + if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); int igroup = group->find(arg1); if (igroup == -1) - error->all("Group ID in variable formula does not exist"); + error->all(FLERR,"Group ID in variable formula does not exist"); Tree *newtree = new Tree(); newtree->type = GMASK; @@ -2886,8 +2883,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"rmask") == 0) { if (tree == NULL) - error->all("Rmask function in equal-style variable formula"); - if (narg != 1) error->all("Invalid special function in variable formula"); + error->all(FLERR,"Rmask function in equal-style variable formula"); + if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); int iregion = region_function(arg1); @@ -2899,12 +2896,12 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"grmask") == 0) { if (tree == NULL) - error->all("Grmask function in equal-style variable formula"); - if (narg != 2) error->all("Invalid special function in variable formula"); + error->all(FLERR,"Grmask function in equal-style variable formula"); + if (narg != 2) error->all(FLERR,"Invalid special function in variable formula"); int igroup = group->find(arg1); if (igroup == -1) - error->all("Group ID in variable formula does not exist"); + error->all(FLERR,"Group ID in variable formula does not exist"); int iregion = region_function(arg2); Tree *newtree = new Tree(); @@ -2934,7 +2931,7 @@ void Variable::peratom2global(int flag, char *word, double *argstack, int &nargstack) { if (atom->map_style == 0) - error->all("Indexed per-atom vector in variable formula without atom map"); + error->all(FLERR,"Indexed per-atom vector in variable formula without atom map"); int index = atom->map(id); @@ -2957,7 +2954,7 @@ void Variable::peratom2global(int flag, char *word, else if (strcmp(word,"fy") == 0) mine = atom->f[index][1]; else if (strcmp(word,"fz") == 0) mine = atom->f[index][2]; - else error->one("Invalid atom vector in variable formula"); + else error->one(FLERR,"Invalid atom vector in variable formula"); } else mine = vector[index*nstride]; @@ -3010,7 +3007,7 @@ void Variable::atom_vector(char *word, Tree **tree, Tree **treestack, int &ntreestack) { if (tree == NULL) - error->all("Atom vector in equal-style variable formula"); + error->all(FLERR,"Atom vector in equal-style variable formula"); Tree *newtree = new Tree(); newtree->type = ATOMARRAY; @@ -3077,7 +3074,7 @@ double Variable::numeric(char *str) if (isdigit(str[i])) continue; if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue; if (str[i] == 'e' || str[i] == 'E') continue; - error->all("Expected floating point parameter in variable definition"); + error->all(FLERR,"Expected floating point parameter in variable definition"); } return atof(str); @@ -3093,7 +3090,7 @@ int Variable::inumeric(char *str) int n = strlen(str); for (int i = 0; i < n; i++) { if (isdigit(str[i]) || str[i] == '-' || str[i] == '+') continue; - error->all("Expected integer parameter in variable definition"); + error->all(FLERR,"Expected integer parameter in variable definition"); } return atoi(str); @@ -3163,7 +3160,7 @@ double Variable::evaluate_boolean(char *str) // ---------------- else if (onechar == '(') { - if (expect == OP) error->all("Invalid Boolean syntax in if command"); + if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command"); expect = OP; char *contents; @@ -3181,7 +3178,7 @@ double Variable::evaluate_boolean(char *str) // ---------------- } else if (isdigit(onechar) || onechar == '.' || onechar == '-') { - if (expect == OP) error->all("Invalid Boolean syntax in if command"); + if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command"); expect = OP; // istop = end of number, including scientific notation @@ -3211,7 +3208,7 @@ double Variable::evaluate_boolean(char *str) } else if (strchr("<>=!&|\0",onechar)) { if (onechar == '=') { if (str[i+1] != '=') - error->all("Invalid Boolean syntax in if command"); + error->all(FLERR,"Invalid Boolean syntax in if command"); op = EQ; i++; } else if (onechar == '!') { @@ -3233,12 +3230,12 @@ double Variable::evaluate_boolean(char *str) } } else if (onechar == '&') { if (str[i+1] != '&') - error->all("Invalid Boolean syntax in if command"); + error->all(FLERR,"Invalid Boolean syntax in if command"); op = AND; i++; } else if (onechar == '|') { if (str[i+1] != '|') - error->all("Invalid Boolean syntax in if command"); + error->all(FLERR,"Invalid Boolean syntax in if command"); op = OR; i++; } else op = DONE; @@ -3250,7 +3247,7 @@ double Variable::evaluate_boolean(char *str) continue; } - if (expect == ARG) error->all("Invalid Boolean syntax in if command"); + if (expect == ARG) error->all(FLERR,"Invalid Boolean syntax in if command"); expect = ARG; // evaluate stack as deep as possible while respecting precedence @@ -3300,10 +3297,10 @@ double Variable::evaluate_boolean(char *str) opstack[nopstack++] = op; - } else error->all("Invalid Boolean syntax in if command"); + } else error->all(FLERR,"Invalid Boolean syntax in if command"); } - if (nopstack) error->all("Invalid Boolean syntax in if command"); - if (nargstack != 1) error->all("Invalid Boolean syntax in if command"); + if (nopstack) error->all(FLERR,"Invalid Boolean syntax in if command"); + if (nargstack != 1) error->all(FLERR,"Invalid Boolean syntax in if command"); return argstack[0]; } diff --git a/src/velocity.cpp b/src/velocity.cpp index c590ece9db..ef95a873a7 100644 --- a/src/velocity.cpp +++ b/src/velocity.cpp @@ -43,9 +43,6 @@ enum{NONE,CONSTANT,EQUAL,ATOM}; #define WARMUP 100 #define SMALL 0.001 -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ Velocity::Velocity(LAMMPS *lmp) : Pointers(lmp) {} @@ -54,12 +51,12 @@ Velocity::Velocity(LAMMPS *lmp) : Pointers(lmp) {} void Velocity::command(int narg, char **arg) { - if (narg < 2) error->all("Illegal velocity command"); + if (narg < 2) error->all(FLERR,"Illegal velocity command"); if (domain->box_exist == 0) - error->all("Velocity command before simulation box is defined"); + error->all(FLERR,"Velocity command before simulation box is defined"); if (atom->natoms == 0) - error->all("Velocity command with no atoms existing"); + error->all(FLERR,"Velocity command with no atoms existing"); // atom masses must all be set @@ -68,7 +65,7 @@ void Velocity::command(int narg, char **arg) // identify group igroup = group->find(arg[0]); - if (igroup == -1) error->all("Could not find velocity group ID"); + if (igroup == -1) error->all(FLERR,"Could not find velocity group ID"); groupbit = group->bitmask[igroup]; // identify style @@ -78,7 +75,7 @@ void Velocity::command(int narg, char **arg) else if (strcmp(arg[1],"scale") == 0) style = SCALE; else if (strcmp(arg[1],"ramp") == 0) style = RAMP; else if (strcmp(arg[1],"zero") == 0) style = ZERO; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); // set defaults @@ -120,7 +117,7 @@ void Velocity::command(int narg, char **arg) void Velocity::init_external(char *extgroup) { igroup = group->find(extgroup); - if (igroup == -1) error->all("Could not find velocity group ID"); + if (igroup == -1) error->all(FLERR,"Could not find velocity group ID"); groupbit = group->bitmask[igroup]; temperature = NULL; @@ -138,7 +135,7 @@ void Velocity::create(double t_desired, int seed) { int i; - if (seed <= 0) error->all("Illegal velocity create command"); + if (seed <= 0) error->all(FLERR,"Illegal velocity create command"); // if temperature = NULL, create a new ComputeTemp with the velocity group @@ -157,7 +154,7 @@ void Velocity::create(double t_desired, int seed) // warn if groups don't match if (igroup != temperature->igroup && comm->me == 0) - error->warning("Mismatch between velocity and compute groups"); + error->warning(FLERR,"Mismatch between velocity and compute groups"); temperature->init(); // store a copy of current velocities @@ -214,11 +211,11 @@ void Velocity::create(double t_desired, int seed) // error check if (atom->natoms > MAXSMALLINT) - error->all("Too big a problem to use velocity create loop all"); + error->all(FLERR,"Too big a problem to use velocity create loop all"); if (atom->tag_enable == 0) - error->all("Cannot use velocity create loop all unless atoms have IDs"); + error->all(FLERR,"Cannot use velocity create loop all unless atoms have IDs"); if (atom->tag_consecutive() == 0) - error->all("Atom IDs must be consecutive for velocity create loop all"); + error->all(FLERR,"Atom IDs must be consecutive for velocity create loop all"); // loop over all atoms in system // generate RNGs for all atoms, only assign to ones I own @@ -379,19 +376,19 @@ void Velocity::set(int narg, char **arg) if (xstyle && !xstr) { if (scale_flag && domain->lattice == NULL) - error->all("Use of velocity with undefined lattice"); + error->all(FLERR,"Use of velocity with undefined lattice"); if (scale_flag) xscale = domain->lattice->xlattice; vx *= xscale; } if (ystyle && !ystr) { if (scale_flag && domain->lattice == NULL) - error->all("Use of velocity with undefined lattice"); + error->all(FLERR,"Use of velocity with undefined lattice"); if (scale_flag) yscale = domain->lattice->ylattice; vy *= yscale; } if (zstyle && !zstr) { if (scale_flag && domain->lattice == NULL) - error->all("Use of velocity with undefined lattice"); + error->all(FLERR,"Use of velocity with undefined lattice"); if (scale_flag) zscale = domain->lattice->zlattice; vz *= zscale; } @@ -400,24 +397,24 @@ void Velocity::set(int narg, char **arg) if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all("Variable name for velocity set does not exist"); + if (xvar < 0) error->all(FLERR,"Variable name for velocity set does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; - else error->all("Variable for velocity set is invalid style"); + else error->all(FLERR,"Variable for velocity set is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all("Variable name for velocity set does not exist"); + if (yvar < 0) error->all(FLERR,"Variable name for velocity set does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; - else error->all("Variable for velocity set is invalid style"); + else error->all(FLERR,"Variable for velocity set is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all("Variable name for velocity set does not exist"); + if (zvar < 0) error->all(FLERR,"Variable name for velocity set does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; - else error->all("Variable for velocity set is invalid style"); + else error->all(FLERR,"Variable for velocity set is invalid style"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) @@ -430,9 +427,9 @@ void Velocity::set(int narg, char **arg) if (domain->dimension == 2) { if (zstyle == CONSTANT && vz != 0.0) - error->all("Cannot set non-zero z velocity for 2d simulation"); + error->all(FLERR,"Cannot set non-zero z velocity for 2d simulation"); if (zstyle == EQUAL || zstyle == ATOM) - error->all("Cannot set variable z velocity for 2d simulation"); + error->all(FLERR,"Cannot set variable z velocity for 2d simulation"); } // allocate vfield array if necessary @@ -527,7 +524,7 @@ void Velocity::scale(int narg, char **arg) // warn if groups don't match if (igroup != temperature->igroup && comm->me == 0) - error->warning("Mismatch between velocity and compute groups"); + error->warning(FLERR,"Mismatch between velocity and compute groups"); temperature->init(); // scale temp to desired value @@ -549,7 +546,7 @@ void Velocity::ramp(int narg, char **arg) // set scale factors if (scale_flag && domain->lattice == NULL) - error->all("Use of velocity with undefined lattice"); + error->all(FLERR,"Use of velocity with undefined lattice"); if (scale_flag) { xscale = domain->lattice->xlattice; @@ -564,10 +561,10 @@ void Velocity::ramp(int narg, char **arg) if (strcmp(arg[0],"vx") == 0) v_dim = 0; else if (strcmp(arg[0],"vy") == 0) v_dim = 1; else if (strcmp(arg[0],"vz") == 0) v_dim = 2; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); if (v_dim == 2 && domain->dimension == 2) - error->all("Velocity ramp in z for a 2d problem"); + error->all(FLERR,"Velocity ramp in z for a 2d problem"); double v_lo,v_hi; if (v_dim == 0) { @@ -585,7 +582,7 @@ void Velocity::ramp(int narg, char **arg) if (strcmp(arg[3],"x") == 0) coord_dim = 0; else if (strcmp(arg[3],"y") == 0) coord_dim = 1; else if (strcmp(arg[3],"z") == 0) coord_dim = 2; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); double coord_lo,coord_hi; if (coord_dim == 0) { @@ -628,7 +625,7 @@ void Velocity::zero(int narg, char **arg) { if (strcmp(arg[0],"linear") == 0) zero_momentum(); else if (strcmp(arg[0],"angular") == 0) zero_rotation(); - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); } /* ---------------------------------------------------------------------- @@ -637,7 +634,7 @@ void Velocity::zero(int narg, char **arg) void Velocity::rescale(double t_old, double t_new) { - if (t_old == 0.0) error->all("Attempting to rescale a 0.0 temperature"); + if (t_old == 0.0) error->all(FLERR,"Attempting to rescale a 0.0 temperature"); double factor = sqrt(t_new/t_old); @@ -662,7 +659,7 @@ void Velocity::zero_momentum() // cannot have 0 atoms in group if (group->count(igroup) == 0) - error->all("Cannot zero momentum of 0 atoms"); + error->all(FLERR,"Cannot zero momentum of 0 atoms"); // compute velocity of center-of-mass of group @@ -695,7 +692,7 @@ void Velocity::zero_rotation() // cannot have 0 atoms in group if (group->count(igroup) == 0) - error->all("Cannot zero momentum of 0 atoms"); + error->all(FLERR,"Cannot zero momentum of 0 atoms"); // compute omega (angular velocity) of group around center-of-mass @@ -742,58 +739,58 @@ void Velocity::zero_rotation() void Velocity::options(int narg, char **arg) { - if (narg < 0) error->all("Illegal velocity command"); + if (narg < 0) error->all(FLERR,"Illegal velocity command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"dist") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"uniform") == 0) dist_flag = 0; else if (strcmp(arg[iarg+1],"gaussian") == 0) dist_flag = 1; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; } else if (strcmp(arg[iarg],"sum") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"no") == 0) sum_flag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) sum_flag = 1; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; } else if (strcmp(arg[iarg],"mom") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"no") == 0) momentum_flag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) momentum_flag = 1; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; } else if (strcmp(arg[iarg],"rot") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"no") == 0) rotation_flag = 0; else if (strcmp(arg[iarg+1],"yes") == 0) rotation_flag = 1; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; } else if (strcmp(arg[iarg],"temp") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); int icompute; for (icompute = 0; icompute < modify->ncompute; icompute++) if (strcmp(arg[iarg+1],modify->compute[icompute]->id) == 0) break; if (icompute == modify->ncompute) - error->all("Could not find velocity temperature ID"); + error->all(FLERR,"Could not find velocity temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all("Velocity temperature ID does not compute temperature"); + error->all(FLERR,"Velocity temperature ID does not compute temperature"); iarg += 2; } else if (strcmp(arg[iarg],"loop") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"all") == 0) loop_flag = ALL; else if (strcmp(arg[iarg+1],"local") == 0) loop_flag = LOCAL; else if (strcmp(arg[iarg+1],"geom") == 0) loop_flag = GEOM; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; } else if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all("Illegal velocity command"); + if (iarg+2 > narg) error->all(FLERR,"Illegal velocity command"); if (strcmp(arg[iarg+1],"box") == 0) scale_flag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scale_flag = 1; - else error->all("Illegal velocity command"); + else error->all(FLERR,"Illegal velocity command"); iarg += 2; - } else error->all("Illegal velocity command"); + } else error->all(FLERR,"Illegal velocity command"); } } diff --git a/src/verlet.cpp b/src/verlet.cpp index 4fc4024f42..7e38367400 100644 --- a/src/verlet.cpp +++ b/src/verlet.cpp @@ -49,7 +49,7 @@ void Verlet::init() // warn if no fixes if (modify->nfix == 0 && comm->me == 0) - error->warning("No fixes defined, atoms won't move"); + error->warning(FLERR,"No fixes defined, atoms won't move"); // virial_style: // 1 if computed explicitly by pair->compute via sum over pair interactions diff --git a/src/write_restart.cpp b/src/write_restart.cpp index 260dcbe3da..6a909ae107 100644 --- a/src/write_restart.cpp +++ b/src/write_restart.cpp @@ -38,9 +38,6 @@ using namespace LAMMPS_NS; -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - // same as read_restart.cpp and tools/restart2data.cpp enum{VERSION,SMALLINT,TAGINT,BIGINT, @@ -76,8 +73,8 @@ WriteRestart::WriteRestart(LAMMPS *lmp) : Pointers(lmp) void WriteRestart::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all("Write_restart command before simulation box is defined"); - if (narg != 1) error->all("Illegal write_restart command"); + error->all(FLERR,"Write_restart command before simulation box is defined"); + if (narg != 1) error->all(FLERR,"Illegal write_restart command"); // if filename contains a "*", replace with current timestep @@ -135,7 +132,7 @@ void WriteRestart::write(char *file) bigint nblocal = atom->nlocal; MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world); if (natoms != atom->natoms && output->thermo->lostflag == ERROR) - error->all("Atom count is inconsistent, cannot write restart file"); + error->all(FLERR,"Atom count is inconsistent, cannot write restart file"); // check if filename contains "%" @@ -158,7 +155,7 @@ void WriteRestart::write(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open restart file %s",hfile); - error->one(str); + error->one(FLERR,str); } if (multiproc) delete [] hfile; } @@ -284,7 +281,7 @@ void WriteRestart::write(char *file) if (fp == NULL) { char str[128]; sprintf(str,"Cannot open restart file %s",perproc); - error->one(str); + error->one(FLERR,str); } delete [] perproc; fwrite(&send_size,sizeof(int),1,fp); From d296662af68cd53b684c3de0bcb731596d2ef2c7 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 18:14:14 +0000 Subject: [PATCH 146/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7004 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/error.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/error.cpp b/src/error.cpp index 283d872baf..c9297eb75d 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -98,7 +98,8 @@ void Error::one(const char *file, int line, const char *str) { int me; MPI_Comm_rank(world,&me); - if (screen) fprintf(screen,"ERROR on proc %d: %s (%s:%d)\n",me,str,file,line); + if (screen) fprintf(screen,"ERROR on proc %d: %s (%s:%d)\n", + me,str,file,line); if (universe->nworlds > 1) fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n", universe->me,str,file,line); From e6fac7cd8a7ba536bc4f0558c9eda24b07a87415 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 18:14:26 +0000 Subject: [PATCH 147/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7005 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_errors.html | 16 ++++++++++------ doc/Section_errors.txt | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/doc/Section_errors.html b/doc/Section_errors.html index bd7722e923..4330576f5c 100644 --- a/doc/Section_errors.html +++ b/doc/Section_errors.html @@ -147,13 +147,17 @@ causing the problem.

      These are two alphabetic lists of the ERROR and WARNING messages LAMMPS prints out and the reason why. If the explanation here is not sufficient, the documentation for the -offending command may help. Grepping the source files for the text of -the error message and staring at the source code and comments is also -not a bad idea! Note that sometimes the same message can be printed -from multiple places in the code. +offending command may help. +Error and warning messages also list the source file and line number +where the error was generated. For example, this message

      -

      Also note that error messages from user-contributed -packages are not listed here. Is such an +

      ERROR: Illegal velocity command (velocity.cpp:78) +

      +

      means that line #78 in the file src/velocity.cpp generated the error. +Looking in the source code may help you figure out what went wrong. +

      +

      Note that error messages from user-contributed +packages are not listed here. If such an error occurs and is not self-explanatory, you'll need to look in the source code or contact the author of the package.

      diff --git a/doc/Section_errors.txt b/doc/Section_errors.txt index 0712fb922f..dab3e05cf6 100644 --- a/doc/Section_errors.txt +++ b/doc/Section_errors.txt @@ -144,13 +144,17 @@ As a last resort, you can send an email directly to the These are two alphabetic lists of the "ERROR"_#error and "WARNING"_#warn messages LAMMPS prints out and the reason why. If the explanation here is not sufficient, the documentation for the -offending command may help. Grepping the source files for the text of -the error message and staring at the source code and comments is also -not a bad idea! Note that sometimes the same message can be printed -from multiple places in the code. +offending command may help. +Error and warning messages also list the source file and line number +where the error was generated. For example, this message -Also note that error messages from "user-contributed -packages"_Section_start.html#start_3 are not listed here. Is such an +ERROR: Illegal velocity command (velocity.cpp:78) + +means that line #78 in the file src/velocity.cpp generated the error. +Looking in the source code may help you figure out what went wrong. + +Note that error messages from "user-contributed +packages"_Section_start.html#start_3 are not listed here. If such an error occurs and is not self-explanatory, you'll need to look in the source code or contact the author of the package. From 7873e97fc350ff6cf24495b95de055a5877cd107 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 18:14:49 +0000 Subject: [PATCH 148/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7006 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 3969e11c17..6aa3a39ddd 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "23 Sep 2011" +#define LAMMPS_VERSION "24 Sep 2011" From c0a3d0aa9a8f5c80166a358be685a6cdb90fa7ae Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 19:23:47 +0000 Subject: [PATCH 149/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7008 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/dump_image.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dump_image.cpp b/src/dump_image.cpp index f01326c815..25dc36109f 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -371,9 +371,9 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : fillLightPhi = PI/6.0; // 30 degrees fillLightTheta = 0; - fillLightColor[0] = 0.9; - fillLightColor[1] = 0.9; - fillLightColor[2] = 0.9; + fillLightColor[0] = 0.45; + fillLightColor[1] = 0.45; + fillLightColor[2] = 0.45; backLightPhi = PI; // 180 degrees backLightTheta = PI/12.0; // 15 degrees @@ -1232,6 +1232,8 @@ void DumpImage::draw_cylinder(double *x, double *y, if (zaxis[0] == camDir[0] && zaxis[1] == camDir[1] && zaxis[2] == camDir[2]) return; + if (zaxis[0] == -camDir[0] && zaxis[1] == -camDir[1] && + zaxis[2] == -camDir[2]) return; MathExtra::cross3(zaxis,camDir,yaxis); MathExtra::norm3(yaxis); From 6b73c2cdf802390d37ae64c44953ea28ddd98017 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 21:01:08 +0000 Subject: [PATCH 150/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7009 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/Makefile.lib | 6 +++++- src/Makefile.list | 6 +++++- src/random_park.cpp | 7 ++++--- src/variable.cpp | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Makefile.lib b/src/Makefile.lib index 79e4d56936..10051e1c20 100644 --- a/src/Makefile.lib +++ b/src/Makefile.lib @@ -29,7 +29,11 @@ clean: @if [ ! -d Obj_$@ ]; then mkdir Obj_$@; fi @cp -p $(SRC) $(INC) Obj_$@ @cp MAKE/Makefile.$@ Obj_$@/Makefile - @cp Makefile.package Obj_$@ + @if [ ! -e Makefile.package ]; \ + then cp Makefile.package.empty Makefile.package; fi + @if [ ! -e Makefile.package.settings ]; \ + then cp Makefile.package.settings.empty Makefile.package.settings; fi + @cp Makefile.package Makefile.package.settings Obj_$@ @cd Obj_$@; \ $(MAKE) $(MFLAGS) "OBJ = $(OBJ)" "INC = $(INC)" "EXE = ../$(EXE)" lib @if [ -d Obj_$@ ]; then cd Obj_$@; rm -f $(SRC) $(INC) Makefile*; fi diff --git a/src/Makefile.list b/src/Makefile.list index fe4b0a96c8..5f755f6ecd 100644 --- a/src/Makefile.list +++ b/src/Makefile.list @@ -29,7 +29,11 @@ clean: @if [ ! -d Obj_$@ ]; then mkdir Obj_$@; fi @cp -p $(SRC) $(INC) Obj_$@ @cp MAKE/Makefile.$@ Obj_$@/Makefile - @cp Makefile.package Obj_$@ + @if [ ! -e Makefile.package ]; \ + then cp Makefile.package.empty Makefile.package; fi + @if [ ! -e Makefile.package.settings ]; \ + then cp Makefile.package.settings.empty Makefile.package.settings; fi + @cp Makefile.package Makefile.package.settings Obj_$@ @cd Obj_$@; \ $(MAKE) $(MFLAGS) "OBJ = $(OBJ)" "INC = $(INC)" "EXE = ../$(EXE)" ../$(EXE) @if [ -d Obj_$@ ]; then cd Obj_$@; rm -f $(SRC) $(INC) Makefile*; fi diff --git a/src/random_park.cpp b/src/random_park.cpp index 456020ff25..6867a61a56 100644 --- a/src/random_park.cpp +++ b/src/random_park.cpp @@ -15,7 +15,6 @@ #include "math.h" #include "random_park.h" -#include "domain.h" #include "error.h" using namespace LAMMPS_NS; @@ -40,7 +39,8 @@ using namespace LAMMPS_NS; RanPark::RanPark(LAMMPS *lmp, int seed_init) : Pointers(lmp) { - if (seed_init <= 0) error->all(FLERR,"Invalid seed for Park random # generator"); + if (seed_init <= 0) + error->all(FLERR,"Invalid seed for Park random # generator"); seed = seed_init; save = 0; } @@ -89,7 +89,8 @@ double RanPark::gaussian() void RanPark::reset(int seed_init) { - if (seed_init <= 0) error->all(FLERR,"Invalid seed for Park random # generator"); + if (seed_init <= 0) + error->all(FLERR,"Invalid seed for Park random # generator"); seed = seed_init; save = 0; } diff --git a/src/variable.cpp b/src/variable.cpp index cab825ff4a..a884455137 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From b942af38b223805a2477fa694b94134ab63fbb7e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 23:46:48 +0000 Subject: [PATCH 151/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7010 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_evaporate.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/fix_evaporate.cpp b/src/fix_evaporate.cpp index a0446c4675..e00d0ca9e3 100644 --- a/src/fix_evaporate.cpp +++ b/src/fix_evaporate.cpp @@ -49,8 +49,10 @@ FixEvaporate::FixEvaporate(LAMMPS *lmp, int narg, char **arg) : strcpy(idregion,arg[5]); int seed = atoi(arg[6]); - if (nevery <= 0 || nflux <= 0) error->all(FLERR,"Illegal fix evaporate command"); - if (iregion == -1) error->all(FLERR,"Region ID for fix evaporate does not exist"); + if (nevery <= 0 || nflux <= 0) + error->all(FLERR,"Illegal fix evaporate command"); + if (iregion == -1) + error->all(FLERR,"Region ID for fix evaporate does not exist"); if (seed <= 0) error->all(FLERR,"Illegal fix evaporate command"); // random number generator, same for all procs @@ -149,7 +151,8 @@ void FixEvaporate::init() } if (molflag && atom->molecule_flag == 0) - error->all(FLERR,"Fix evaporate molecule requires atom attribute molecule"); + error->all(FLERR, + "Fix evaporate molecule requires atom attribute molecule"); } /* ---------------------------------------------------------------------- @@ -178,10 +181,11 @@ void FixEvaporate::pre_exchange() // ncount = # of deletable atoms in region that I own // nall = # on all procs // nbefore = # on procs before me - // list[ncount] = list of local indices + // list[ncount] = list of local indices of atoms I can delete double **x = atom->x; int *mask = atom->mask; + int *tag = atom->tag; int nlocal = atom->nlocal; int ncount = 0; @@ -229,7 +233,7 @@ void FixEvaporate::pre_exchange() // keep ndel,ndeltopo,ncount,nall,nbefore current after each mol deletion } else { - int me,proc,iatom,imolecule,ndelone; + int me,proc,iatom,imolecule,ndelone,ndelall; int *molecule = atom->molecule; ndeltopo[0] = ndeltopo[1] = ndeltopo[2] = ndeltopo[3] = 0; @@ -249,6 +253,7 @@ void FixEvaporate::pre_exchange() // bcast mol ID to delete all atoms from // if mol ID > 0, delete any atom in molecule and decrement counters // if mol ID == 0, delete single iatom + // be careful to delete correct # of bond,angle,etc for newton on or off MPI_Allreduce(&me,&proc,1,MPI_INT,MPI_MAX,world); MPI_Bcast(&imolecule,1,MPI_INT,proc,world); @@ -262,8 +267,7 @@ void FixEvaporate::pre_exchange() if (force->newton_bond) ndeltopo[0] += atom->num_bond[i]; else { for (j = 0; j < atom->num_bond[i]; j++) { - m = atom->map(atom->bond_atom[i][j]); - if (m >= 0 && m < nlocal) ndeltopo[0]++; + if (tag[i] < atom->bond_atom[i][j]) ndeltopo[0]++; } } } @@ -312,8 +316,11 @@ void FixEvaporate::pre_exchange() } // update ndel,ncount,nall,nbefore + // ndelall is total atoms deleted on this iteration + // ncount is already correct, so resum to get nall and nbefore - MPI_Allreduce(&ndelone,&ndel,1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(&ndelone,&ndelall,1,MPI_INT,MPI_SUM,world); + ndel += ndelall; MPI_Allreduce(&ncount,&nall,1,MPI_INT,MPI_SUM,world); MPI_Scan(&ncount,&nbefore,1,MPI_INT,MPI_SUM,world); nbefore -= ncount; From 9c1ec9764e927a666db99f772048393abc01bd66 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 23:48:54 +0000 Subject: [PATCH 152/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7011 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 7cda5f2b3e..a258a335e9 100644 --- a/README +++ b/README @@ -39,3 +39,4 @@ Point your browser at any of these files to get started: doc/Manual.html the LAMMPS manual doc/Section_intro.html hi-level introduction to LAMMPS doc/Section_start.html how to build and use LAMMPS +doc/Developer.pdf LAMMPS developer guide From afc72c79134984a75fa30b108694f7d7a229945f Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 23 Sep 2011 23:49:05 +0000 Subject: [PATCH 153/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7012 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 6aa3a39ddd..ba2ffff87c 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "24 Sep 2011" +#define LAMMPS_VERSION "25 Sep 2011" From 28cb3f7a400ea27d539358619a6c8d8f342d1f8b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 29 Sep 2011 16:14:18 +0000 Subject: [PATCH 154/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7014 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/pointers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pointers.h b/src/pointers.h index d00665c973..963561792f 100644 --- a/src/pointers.h +++ b/src/pointers.h @@ -31,8 +31,8 @@ namespace LAMMPS_NS { #define FLERR __FILE__,__LINE__ -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) class Pointers { public: From 8e637f06fabb40265615ddf06365372f8f5c7a07 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 29 Sep 2011 16:17:58 +0000 Subject: [PATCH 155/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7015 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index ba2ffff87c..e8f4df30ba 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "25 Sep 2011" +#define LAMMPS_VERSION "29 Sep 2011" From 4c107e07a44dced13e96fbbdba0a2b746696ad1e Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 30 Sep 2011 16:03:38 +0000 Subject: [PATCH 156/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7017 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- tools/restart2data.cpp | 104 ++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 59 deletions(-) diff --git a/tools/restart2data.cpp b/tools/restart2data.cpp index ec5dc81d22..ad93313648 100644 --- a/tools/restart2data.cpp +++ b/tools/restart2data.cpp @@ -13,9 +13,7 @@ // Convert a LAMMPS binary restart file into an ASCII text data file // -// Syntax: restart2data switch arg ... restart-file data-file (input-file) -// optional switch = -s -// arg = suffix to remove from style names +// Syntax: restart2data restart-file data-file (input-file) // restart-file and data-file are mandatory // input-file is optional // if specified it will contain LAMMPS input script commands @@ -80,7 +78,6 @@ class Data { char *version; int size_smallint,size_tagint,size_bigint; - char *suffix; bigint ntimestep; int nprocs; char *unit_style; @@ -316,7 +313,7 @@ int atom_molecular(double *, Data &, int); int atom_peri(double *, Data &, int); int atom_sphere(double *, Data &, int); -void strip_suffix(char *, char *); +void strip_suffix(char *); int read_int(FILE *fp); double read_double(FILE *fp); @@ -331,29 +328,16 @@ int main (int narg, char **arg) { // process command-line args - char *suffix = NULL; - int iarg = 1; - while (iarg < narg) { - if (strcmp(arg[iarg],"-h") == 0) { - printf("Syntax: restart2data switch arg ... " - "restart-file data-file (input-file)\n"); - printf(" optional switch = -s"); - printf(" arg = suffix to remove from style names"); - printf(" restart-file and data-file are mandatory"); - printf(" input-file is optional"); - printf(" if specified it will contain LAMMPS input script commands"); - printf(" for mass and force field info"); - printf(" only a few force field styles support this option"); - } else if (strcmp(arg[iarg],"-s") == 0) { - if (iarg+2 > narg) { - printf("Syntax: restart2data switch arg ... " - "restart-file data-file (input-file)\n"); - return 1; - } - suffix = arg[iarg+1]; - iarg += 2; - } else break; + if (strcmp(arg[iarg],"-h") == 0) { + printf("Syntax: restart2data switch arg ... " + "restart-file data-file (input-file)\n"); + printf(" restart-file and data-file are mandatory"); + printf(" input-file is optional"); + printf(" if specified it will contain LAMMPS input script commands"); + printf(" for mass and force field info"); + printf(" only a few force field styles support this option"); + return 0; } if ((narg-iarg != 2) && (narg-iarg != 3)) { @@ -377,7 +361,7 @@ int main (int narg, char **arg) FILE *fp; int multiproc = 0; - if (ptr = strchr(restartfile,'%')) { + if ( (ptr = strchr(restartfile,'%')) ) { multiproc = 1; char *basefile = new char[strlen(restartfile) + 16]; *ptr = '\0'; @@ -399,12 +383,6 @@ int main (int narg, char **arg) Data data; - if (suffix) { - int n = strlen(suffix) + 1; - data.suffix = new char[n]; - strcpy(data.suffix,suffix); - } else data.suffix = NULL; - header(fp,data); if (data.size_smallint != sizeof(int) || data.size_tagint != sizeof(tagint) || @@ -500,7 +478,7 @@ int main (int narg, char **arg) void header(FILE *fp, Data &data) { - char *version = "25 Jun 2011"; + char *version = "19 Aug 2011"; data.triclinic = 0; @@ -551,7 +529,7 @@ void header(FILE *fp, Data &data) data.style_molecular = data.style_peri = data.style_sphere = 0; data.atom_style = read_char(fp); - strip_suffix(data.atom_style,data.suffix); + strip_suffix(data.atom_style); set_style(data.atom_style,data,1); if (strcmp(data.atom_style,"hybrid") == 0) { @@ -641,7 +619,6 @@ void groups(FILE *fp) { int ngroup = read_int(fp); - int n; char *name; // use count to not change restart format with deleted groups @@ -698,23 +675,23 @@ void force_fields(FILE *fp, Data &data) if (flag == PAIR) { data.pair_style = read_char(fp); - strip_suffix(data.pair_style,data.suffix); + strip_suffix(data.pair_style); pair(fp,data,data.pair_style,1); } else if (flag == BOND) { data.bond_style = read_char(fp); - strip_suffix(data.bond_style,data.suffix); + strip_suffix(data.bond_style); bond(fp,data); } else if (flag == ANGLE) { data.angle_style = read_char(fp); - strip_suffix(data.angle_style,data.suffix); + strip_suffix(data.angle_style); angle(fp,data); } else if (flag == DIHEDRAL) { data.dihedral_style = read_char(fp); - strip_suffix(data.dihedral_style,data.suffix); + strip_suffix(data.dihedral_style); dihedral(fp,data); } else if (flag == IMPROPER) { data.improper_style = read_char(fp); - strip_suffix(data.improper_style,data.suffix); + strip_suffix(data.improper_style); improper(fp,data); } else { printf("ERROR: Invalid flag in force fields section of restart file %d\n", @@ -3330,7 +3307,7 @@ void Data::write(FILE *fp, FILE *fp2) fprintf(fp,"\nAtoms\n\n"); int ix,iy,iz; - for (uint64_t i = 0; i < natoms; i++) { + for (bigint i = 0; i < natoms; i++) { ix = (image[i] & 1023) - 512; iy = (image[i] >> 10 & 1023) - 512; @@ -3371,7 +3348,7 @@ void Data::write(FILE *fp, FILE *fp2) if (natoms) { fprintf(fp,"\nVelocities\n\n"); - for (uint64_t i = 0; i < natoms; i++) + for (bigint i = 0; i < natoms; i++) if (style_hybrid == 0) { if (style_angle) write_vel_angle(fp,i); @@ -3406,7 +3383,7 @@ void Data::write(FILE *fp, FILE *fp2) if (nellipsoids) { fprintf(fp,"\nEllipsoids\n\n"); - for (uint64_t i = 0; i < natoms; i++) { + for (bigint i = 0; i < natoms; i++) { if (ellipsoid[i]) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e " "%-1.16e %-1.16e %-1.16e %-1.16e \n", @@ -3417,21 +3394,21 @@ void Data::write(FILE *fp, FILE *fp2) if (nbonds) { fprintf(fp,"\nBonds\n\n"); - for (uint64_t i = 0; i < nbonds; i++) + for (bigint i = 0; i < nbonds; i++) fprintf(fp,BIGINT_FORMAT " %d %d %d\n", i+1,bond_type[i],bond_atom1[i],bond_atom2[i]); } if (nangles) { fprintf(fp,"\nAngles\n\n"); - for (uint64_t i = 0; i < nangles; i++) + for (bigint i = 0; i < nangles; i++) fprintf(fp,BIGINT_FORMAT " %d %d %d %d\n", i+1,angle_type[i],angle_atom1[i],angle_atom2[i],angle_atom3[i]); } if (ndihedrals) { fprintf(fp,"\nDihedrals\n\n"); - for (uint64_t i = 0; i < ndihedrals; i++) + for (bigint i = 0; i < ndihedrals; i++) fprintf(fp,BIGINT_FORMAT " %d %d %d %d %d\n", i+1,dihedral_type[i],dihedral_atom1[i],dihedral_atom2[i], dihedral_atom3[i],dihedral_atom4[i]); @@ -3439,7 +3416,7 @@ void Data::write(FILE *fp, FILE *fp2) if (nimpropers) { fprintf(fp,"\nImpropers\n\n"); - for (uint64_t i = 0; i < nimpropers; i++) + for (bigint i = 0; i < nimpropers; i++) fprintf(fp,BIGINT_FORMAT " %d %d %d %d %d\n", i+1,improper_type[i],improper_atom1[i],improper_atom2[i], improper_atom3[i],improper_atom4[i]); @@ -3509,7 +3486,7 @@ void Data::write_atom_molecular(FILE *fp, int i, int ix, int iy, int iz) void Data::write_atom_peri(FILE *fp, int i, int ix, int iy, int iz) { - fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d", + fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d", tag[i],type[i],vfrac[i],rmass[i],x[i],y[i],z[i],ix,iy,iz); } @@ -3562,7 +3539,7 @@ void Data::write_atom_molecular_extra(FILE *fp, int i) void Data::write_atom_peri_extra(FILE *fp, int i) { - fprintf(fp," %-1.16e %-1.16e %-1.16e",vfrac[i],rmass[i]); + fprintf(fp," %-1.16e %-1.16e",vfrac[i],rmass[i]); } // --------------------------------------------------------------------- @@ -3649,17 +3626,26 @@ void Data::write_vel_molecular_extra(FILE *fp, int i) {} void Data::write_vel_peri_extra(FILE *fp, int i) {} // --------------------------------------------------------------------- -// strip suffix from style name if suffix is defined +// strip known accelerator suffixes from style name // --------------------------------------------------------------------- -void strip_suffix(char *style, char *suffix) +void strip_suffix(char *style) { - if (!suffix) return; - int n = strlen(suffix) + 2; - char *esuffix = new char[n]; - sprintf(esuffix,"/%s",suffix); - char *ptr = strstr(style,esuffix); - if (ptr && ptr-style+1+strlen(suffix) == strlen(style)) *ptr = '\0'; + char *slash = strrchr(style,'/'); + if (slash == NULL) return; + + int i=0; + + const char *suffix_list[] = { "/opt", "/gpu", "/cuda", "/omp", NULL }; + const char *suffix = suffix_list[0]; + while (suffix != NULL) { + if (strcmp(slash,suffix) == 0) { + *slash = '\0'; + return; + } + ++i; + suffix = suffix_list[i]; + } } // --------------------------------------------------------------------- From 7d2dd1a90f9260d5d51e9df5b918e9e86f62529b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 30 Sep 2011 16:56:12 +0000 Subject: [PATCH 157/246] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7018 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/Section_commands.html | 10 +++++----- doc/Section_commands.txt | 2 ++ doc/Section_start.html | 17 +++++++++-------- doc/Section_start.txt | 17 +++++++++-------- doc/fix_imd.html | 16 +++++----------- doc/fix_imd.txt | 18 ++++++------------ doc/pair_lj.html | 4 ++++ doc/pair_lj.txt | 2 ++ 8 files changed, 42 insertions(+), 44 deletions(-) diff --git a/doc/Section_commands.html b/doc/Section_commands.html index c5303b94d9..b2e5f83217 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -455,11 +455,11 @@ package. lj/charmm/coul/charmm/implicit/cudalj/charmm/coul/long/cudalj/charmm/coul/long/gpulj/charmm/coul/long/opt lj/class2/coul/cut/cudalj/class2/coul/long/cudalj/class2/coul/long/gpulj/class2/cuda lj/class2/gpulj/cut/coul/cut/cudalj/cut/coul/cut/gpulj/cut/coul/debye/cuda -lj/cut/coul/long/cudalj/cut/coul/long/gpulj/cut/cudalj/cut/experimental/cuda -lj/cut/gpulj/cut/optlj/expand/cudalj/expand/gpu -lj/gromacs/coul/gromacs/cudalj/gromacs/cudalj/smooth/cudalj96/cut/cuda -lj96/cut/gpumorse/cudamorse/gpumorse/opt -resquared/gpu +lj/cut/coul/long/cudalj/cut/coul/long/gpulj/cut/coul/long/optlj/cut/coul/long/tip4p/opt +lj/cut/cudalj/cut/experimental/cudalj/cut/gpulj/cut/opt +lj/expand/cudalj/expand/gpulj/gromacs/coul/gromacs/cudalj/gromacs/cuda +lj/smooth/cudalj96/cut/cudalj96/cut/gpumorse/cuda +morse/gpumorse/optresquared/gpu
      diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 3fb890bed9..b4aa95e4c8 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -728,6 +728,8 @@ package"_Section_accelerate.html. "lj/cut/coul/debye/cuda"_pair_lj.html, "lj/cut/coul/long/cuda"_pair_lj.html, "lj/cut/coul/long/gpu"_pair_lj.html, +"lj/cut/coul/long/opt"_pair_lj.html, +"lj/cut/coul/long/tip4p/opt"_pair_lj.html, "lj/cut/cuda"_pair_lj.html, "lj/cut/experimental/cuda"_pair_lj.html, "lj/cut/gpu"_pair_lj.html, diff --git a/doc/Section_start.html b/doc/Section_start.html index ef27205304..976e2666e9 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -248,14 +248,15 @@ vendor-provided MPI which the compiler has no trouble finding. file (MPI_INC) and the MPI library file (MPI_PATH) are found and the name of the library file (MPI_LIB).

      -

      If you are installing MPI yourself, we recommend Argonne's MPICH 1.2 -or 2.0 or OpenMPI. MPICH can be downloaded from the Argonne MPI -site. OpenMPI can be downloaded the -OpenMPI site. LAM MPI should also work. If -you are running on a big parallel platform, your system people or the -vendor should have already installed a version of MPI, which will be -faster than MPICH or OpenMPI or LAM, so find out how to build and link -with it. If you use MPICH or OpenMPI or LAM, you will have to +

      If you are installing MPI yourself, we recommend Argonne's MPICH2 +or OpenMPI. MPICH can be downloaded from the Argonne MPI +site. OpenMPI can +be downloaded from the OpenMPI site. +Other MPI packages should also work. If you are running on a big +parallel platform, your system people or the vendor should have +already installed a version of MPI, which is likely to be faster +than a self-installed MPICH or OpenMPI, so find out how to build +and link with it. If you use MPICH or OpenMPI, you will have to configure and build it for your platform. The MPI configure script should have compiler options to enable you to use the same compiler you are using for the LAMMPS build, which can avoid problems that can diff --git a/doc/Section_start.txt b/doc/Section_start.txt index 5b8e082868..fad3959e79 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -243,14 +243,15 @@ Failing this, with these 3 variables you can specify where the mpi.h file (MPI_INC) and the MPI library file (MPI_PATH) are found and the name of the library file (MPI_LIB). -If you are installing MPI yourself, we recommend Argonne's MPICH 1.2 -or 2.0 or OpenMPI. MPICH can be downloaded from the "Argonne MPI -site"_http://www-unix.mcs.anl.gov/mpi. OpenMPI can be downloaded the -"OpenMPI site"_http://www.open-mpi.org. LAM MPI should also work. If -you are running on a big parallel platform, your system people or the -vendor should have already installed a version of MPI, which will be -faster than MPICH or OpenMPI or LAM, so find out how to build and link -with it. If you use MPICH or OpenMPI or LAM, you will have to +If you are installing MPI yourself, we recommend Argonne's MPICH2 +or OpenMPI. MPICH can be downloaded from the "Argonne MPI +site"_http://www.mcs.anl.gov/research/projects/mpich2/. OpenMPI can +be downloaded from the "OpenMPI site"_http://www.open-mpi.org. +Other MPI packages should also work. If you are running on a big +parallel platform, your system people or the vendor should have +already installed a version of MPI, which is likely to be faster +than a self-installed MPICH or OpenMPI, so find out how to build +and link with it. If you use MPICH or OpenMPI, you will have to configure and build it for your platform. The MPI configure script should have compiler options to enable you to use the same compiler you are using for the LAMMPS build, which can avoid problems that can diff --git a/doc/fix_imd.html b/doc/fix_imd.html index 529fa96864..1d89148879 100644 --- a/doc/fix_imd.html +++ b/doc/fix_imd.html @@ -50,10 +50,11 @@ visualization program, so that it can monitor the progress of the simulation and interactively apply forces to selected atoms.

      If LAMMPS is compiled with the preprocessor flag -DLAMMPS_ASYNC_IMD -then fix imd will use posix threads to spawn a thread on MPI rank 0 in -order to offload data reading and writing from the main execution -thread and potentiall lower the inferred latencies for slow -communication links. This feature has only been tested under linux. +then fix imd will use POSIX threads to spawn a IMD communication +thread on MPI rank 0 in order to offload data reading and writing +from the main execution thread and potentially lower the inferred +latencies for slow communication links. This feature has only been +tested under linux.

      There are example scripts for using this package with LAMMPS in examples/USER/imd. Additional examples and a driver for use with the @@ -155,13 +156,6 @@ This fix is not invoked during energy minimization LAMMPS was built with that package. See the Making LAMMPS section for more info.

      -

      On platforms that support multi-threading, this fix can be compiled in -a way that the coordinate transfers to the IMD client can be handled -from a separate thread, when LAMMPS is compiled with the --DLAMMPS_ASYNC_IMD preprocessor flag. This should to keep MD loop -times low and transfer rates high, especially for systems with many -atoms and for slow connections. -

      When used in combination with VMD, a topology or coordinate file has to be loaded, which matches (in number and ordering of atoms) the group the fix is applied to. The fix internally sorts atom IDs by diff --git a/doc/fix_imd.txt b/doc/fix_imd.txt index 246cb36e0c..283755a796 100644 --- a/doc/fix_imd.txt +++ b/doc/fix_imd.txt @@ -42,10 +42,11 @@ visualization program"_VMD, so that it can monitor the progress of the simulation and interactively apply forces to selected atoms. If LAMMPS is compiled with the preprocessor flag -DLAMMPS_ASYNC_IMD -then fix imd will use posix threads to spawn a thread on MPI rank 0 in -order to offload data reading and writing from the main execution -thread and potentiall lower the inferred latencies for slow -communication links. This feature has only been tested under linux. +then fix imd will use POSIX threads to spawn a IMD communication +thread on MPI rank 0 in order to offload data reading and writing +from the main execution thread and potentially lower the inferred +latencies for slow communication links. This feature has only been +tested under linux. There are example scripts for using this package with LAMMPS in examples/USER/imd. Additional examples and a driver for use with the @@ -125,7 +126,7 @@ If IMD control messages are received, a line of text describing the message and its effect will be printed to the LAMMPS output screen, if screen output is active. -:link(VMD,http://www.ks.uiuc.edu/Research/vmd)x +:link(VMD,http://www.ks.uiuc.edu/Research/vmd) :link(imdvmd,http://www.ks.uiuc.edu/Research/vmd/imd/) :link(vrpnicms,http://sites.google.com/site/akohlmey/software/vrpn-icms) @@ -145,13 +146,6 @@ This fix is part of the USER-MISC package. It is only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. -On platforms that support multi-threading, this fix can be compiled in -a way that the coordinate transfers to the IMD client can be handled -from a separate thread, when LAMMPS is compiled with the --DLAMMPS_ASYNC_IMD preprocessor flag. This should to keep MD loop -times low and transfer rates high, especially for systems with many -atoms and for slow connections. - When used in combination with VMD, a topology or coordinate file has to be loaded, which matches (in number and ordering of atoms) the group the fix is applied to. The fix internally sorts atom IDs by diff --git a/doc/pair_lj.html b/doc/pair_lj.html index 53a058b324..9283346637 100644 --- a/doc/pair_lj.html +++ b/doc/pair_lj.html @@ -35,8 +35,12 @@

    Wi7Z363+(tR8Isk1mjn)mU@>^^# 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%0Aw+oZN#ujjNk?jJz#G!lj{!@gfMS9 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 nnxTmuVHL4_T6w>##>7kWh}h5K_ngy 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