diff --git a/src/KSPACE/pair_lj_long_coul_long.cpp b/src/KSPACE/pair_lj_long_coul_long.cpp index 98ccb04ae7..d09e897a74 100644 --- a/src/KSPACE/pair_lj_long_coul_long.cpp +++ b/src/KSPACE/pair_lj_long_coul_long.cpp @@ -13,6 +13,8 @@ /* ---------------------------------------------------------------------- Contributing author: Pieter J. in 't Veld (SNL) + Tabulation for long-range dispersion added by Wayne Mitchell (Loyola + University New Orleans) ------------------------------------------------------------------------- */ #include "math.h" @@ -51,6 +53,7 @@ PairLJLongCoulLong::PairLJLongCoulLong(LAMMPS *lmp) : Pair(lmp) dispersionflag = ewaldflag = pppmflag = 1; respa_enable = 1; ftable = NULL; + fdisptable = NULL; qdist = 0.0; } @@ -82,22 +85,19 @@ void PairLJLongCoulLong::settings(int narg, char **arg) options(arg, 6); options(++arg, 1); if (!comm->me && ewald_order & (1<<6)) - error->warning(FLERR,"Mixing forced for LJ coefficients"); + error->warning(FLERR,"Mixing forced for lj coefficients"); if (!comm->me && ewald_order == ((1<<1) | (1<<6))) - error->warning(FLERR, - "Using largest cutoff for pair_style lj/long/coul/long"); + error->warning(FLERR,"Using largest cut-off for lj/coul long long"); if (!*(++arg)) - error->all(FLERR,"Cutoffs missing in pair_style lj/long/coul/long"); + error->all(FLERR,"Cut-offs missing in pair_style lj/coul"); if (!((ewald_order^ewald_off) & (1<<1))) - error->all(FLERR, - "Coulomb cut not supported in pair_style lj/long/coul/long"); - cut_lj_global = force->numeric(*(arg++)); + error->all(FLERR,"Coulombic cut not supported in pair_style lj/coul"); cut_lj_global = force->numeric(*(arg++)); if (*arg && ((ewald_order & 0x42) == 0x42)) - error->all(FLERR,"Only one cutoff allowed when requesting all long"); + error->all(FLERR,"Only one cut-off allowed when requesting all long"); if (narg == 4) cut_coul = force->numeric(*arg); else cut_coul = cut_lj_global; - if (allocated) { + if (allocated) { int i,j; for (i = 1; i <= atom->ntypes; i++) for (j = i+1; j <= atom->ntypes; j++) @@ -228,7 +228,8 @@ void PairLJLongCoulLong::init_style() // require an atom style with charge defined if (!atom->q_flag && (ewald_order&(1<<1))) - error->all(FLERR,"Pair style lj/long/coul/long requires atom attribute q"); + error->all(FLERR, + "Invoking coulombic in pair style lj/coul requires atom attribute q"); // request regular or rRESPA neighbor lists @@ -281,10 +282,12 @@ void PairLJLongCoulLong::init_style() error->all(FLERR,"Pair style requires a KSpace style"); if (force->kspace) g_ewald = force->kspace->g_ewald; if (force->kspace) g_ewald_6 = force->kspace->g_ewald_6; - + // setup force tables - + if (ncoultablebits) init_tables(cut_coul,cut_respa); + if (ndisptablebits) init_tables_disp(cut_lj_global); + } /* ---------------------------------------------------------------------- @@ -526,22 +529,40 @@ void PairLJLongCoulLong::compute(int eflag, int vflag) 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 = + if (order6) { // long-range lj + if(!ndisptablebits || rsq <= tabinnerdispsq) { // series real space + 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]- + 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]; + if (eflag) + evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]; + } + } + else { // table real space + register union_int_float_t disp_t; + disp_t.f = rsq; + register const int disp_k = (disp_t.i & ndispmask)>>ndispshiftbits; + register double f_disp = (rsq-rdisptable[disp_k])*drdisptable[disp_k]; + register double rn = r2inv*r2inv*r2inv; + if (ni == 0) { + force_lj = (rn*=rn)*lj1i[typej]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[typej]; + if (eflag) evdwl = rn*lj3i[typej]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[typej]; + } + else { // special case + register double f = special_lj[ni], t = rn*(1.0-f); + force_lj = f*(rn *= rn)*lj1i[typej]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[typej]+t*lj2i[typej]; + if (eflag) evdwl = f*rn*lj3i[typej]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[typej]+t*lj4i[typej]; + } } } else { // cut lj @@ -558,6 +579,7 @@ void PairLJLongCoulLong::compute(int eflag, int vflag) } } } + else force_lj = evdwl = 0.0; fpair = (force_coul+force_lj)*r2inv; @@ -701,7 +723,7 @@ void PairLJLongCoulLong::compute_middle() for (; ineighx, *x0 = x[0]; double **f = atom->f, *f0 = f[0], *fi = f0; double *q = atom->q; @@ -777,7 +799,7 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) double *special_lj = force->special_lj; int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; - + int i, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni, respa_flag; double qi = 0.0, qri = 0.0; @@ -786,16 +808,16 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) double g2 = g_ewald_6*g_ewald_6, g6 = g2*g2*g2, g8 = g6*g2; double respa_lj = 0.0, respa_coul = 0.0, frespa = 0.0; vector xi, d; - + double cut_in_off = cut_respa[2]; double cut_in_on = cut_respa[3]; - + double cut_in_diff = cut_in_on - cut_in_off; double cut_in_off_sq = cut_in_off*cut_in_off; double cut_in_on_sq = cut_in_on*cut_in_on; - + ineighn = (ineigh = list->ilist)+list->inum; - + for (; ineighfirstneigh[i])+list->numneigh[i]; - + for (; jneigh= cutsqi[typej = type[j]]) continue; r2inv = 1.0/rsq; - + frespa = 1.0; // check whether and how to compute respa corrections respa_coul = 0; respa_lj = 0; @@ -826,7 +848,7 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) register double rsw = (sqrt(rsq)-cut_in_off)/cut_in_diff; frespa = 1-rsw*rsw*(3.0-2.0*rsw); } - + if (order1 && (rsq < cut_coulsq)) { // coulombic if (!ncoultablebits || rsq <= tabinnersq) { // series real space register double r = sqrt(rsq), s = qri*q[j]; @@ -867,6 +889,7 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) } } } + else force_coul = respa_coul = ecoul = 0.0; if (rsq < cut_ljsqi[typej]) { // lennard-jones @@ -875,19 +898,37 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) frespa*rn*(rn*lj1i[typej]-lj2i[typej]) : frespa*rn*(rn*lj1i[typej]-lj2i[typej])*special_lj[ni]; if (order6) { // long-range form - 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-respa_lj; - if (eflag) evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2; + if (!ndisptablebits || rsq <= tabinnerdispsq) { + 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-respa_lj; + if (eflag) evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2; + } + else { // correct for special + 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]-respa_lj; + if (eflag) + evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]; + } } - else { // correct for special - 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]-respa_lj; - if (eflag) - evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]; + else { // table real space + register union_int_float_t disp_t; + disp_t.f = rsq; + register const int disp_k = (disp_t.i & ndispmask)>>ndispshiftbits; + register double f_disp = (rsq-rdisptable[disp_k])*drdisptable[disp_k]; + register double rn = r2inv*r2inv*r2inv; + if (ni == 0) { + force_lj = (rn*=rn)*lj1i[typej]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[typej]-respa_lj; + if (eflag) evdwl = rn*lj3i[typej]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[typej]; + } + else { // special case + register double f = special_lj[ni], t = rn*(1.0-f); + force_lj = f*(rn *= rn)*lj1i[typej]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[typej]+t*lj2i[typej]-respa_lj; + if (eflag) evdwl = f*rn*lj3i[typej]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[typej]+t*lj4i[typej]; + } } } else { // cut form @@ -904,9 +945,9 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) } } else force_lj = respa_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; @@ -918,11 +959,11 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) fi[1] += d[1]*fpair; fi[2] += d[2]*fpair; } - + if (evflag) { - fvirial = (force_coul + force_lj + respa_coul + respa_lj)*r2inv; - ev_tally(i,j,nlocal,newton_pair, - evdwl,ecoul,fvirial,d[0],d[1],d[2]); + fvirial = (force_coul + force_lj + respa_coul + respa_lj)*r2inv; + ev_tally(i,j,nlocal,newton_pair, + evdwl,ecoul,fvirial,d[0],d[1],d[2]); } } } diff --git a/src/KSPACE/pair_lj_long_coul_long.h b/src/KSPACE/pair_lj_long_coul_long.h index a47565886a..67fe5a9b6b 100644 --- a/src/KSPACE/pair_lj_long_coul_long.h +++ b/src/KSPACE/pair_lj_long_coul_long.h @@ -19,7 +19,7 @@ PairStyle(lj/long/coul/long,PairLJLongCoulLong) #ifndef LMP_PAIR_LJ_LONG_COUL_LONG_H #define LMP_PAIR_LJ_LONG_COUL_LONG_H - + #include "pair.h" namespace LAMMPS_NS { @@ -44,9 +44,9 @@ class PairLJLongCoulLong : public Pair { double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); - void compute_inner(); - void compute_middle(); - void compute_outer(int, int); + virtual void compute_inner(); + virtual void compute_middle(); + virtual void compute_outer(int, int); protected: double cut_lj_global; @@ -68,50 +68,3 @@ class PairLJLongCoulLong : public Pair { #endif #endif - -/* ERROR/WARNING messages: - -E: Illegal ... command - -Self-explanatory. Check the input script syntax and compare to the -documentation for the command. You can use -echo screen as a -command-line option when running LAMMPS to see the offending line. - -W: Mixing forced for LJ coefficients - -Self-explanatory. - -W: Using largest cutoff for pair_style lj/long/coul/long - -Self-explanatory. - -E: Cutoffs missing in pair_style lj/long/coul/long - -Self-explanatory. - -E: Coulomb cut not supported in pair_style lj/long/coul/long - -Must use long-range Coulombic interactions. - -E: Only one cutoff allowed when requesting all long - -Self-explanatory. - -E: Incorrect args for pair coefficients - -Self-explanatory. Check the input script or data file. - -E: Pair style lj/long/coul/long requires atom attribute q - -The atom style defined does not have this attribute. - -E: Pair style requires a KSpace style - -No kspace style is defined. - -E: Pair cutoff < Respa interior cutoff - -One or more pairwise cutoffs are too short to use with the specified -rRESPA cutoffs. - -*/ diff --git a/src/pair.cpp b/src/pair.cpp index 77a596f3d4..ef4821db39 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -75,7 +75,9 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) tail_flag = 0; etail = ptail = etail_ij = ptail_ij = 0.0; ncoultablebits = 12; + ndisptablebits = 12; tabinner = sqrt(2.0); + tabinner_disp = sqrt(2.0); allocated = 0; suffix_flag = Suffix::NONE; @@ -126,10 +128,20 @@ void Pair::modify_params(int narg, char **arg) if (ncoultablebits > sizeof(float)*CHAR_BIT) error->all(FLERR,"Too many total bits for bitmapped lookup table"); iarg += 2; + } else if (strcmp(arg[iarg],"table/disp") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); + ndisptablebits = atoi(arg[iarg+1]); + if (ndisptablebits > sizeof(float)*CHAR_BIT) + 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(FLERR,"Illegal pair_modify command"); tabinner = atof(arg[iarg+1]); iarg += 2; + } else if (strcmp(arg[iarg],"tabinner/disp") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); + tabinner_disp = atof(arg[iarg+1]); + iarg += 2; } else if (strcmp(arg[iarg],"tail") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) tail_flag = 1; @@ -245,7 +257,7 @@ void Pair::init_list(int which, NeighList *ptr) } /* ---------------------------------------------------------------------- - setup force tables used in compute routines + setup Coulomb force tables used in compute routines ------------------------------------------------------------------------- */ void Pair::init_tables(double cut_coul, double *cut_respa) @@ -255,7 +267,7 @@ void Pair::init_tables(double cut_coul, double *cut_respa) double qqrd2e = force->qqrd2e; if (force->kspace == NULL) - error->all(FLERR,"Pair style requires a KSpace style"); + error->all(FLERR,"Pair style requres a KSpace style"); double g_ewald = force->kspace->g_ewald; double cut_coulsq = cut_coul * cut_coul; @@ -455,7 +467,111 @@ void Pair::init_tables(double cut_coul, double *cut_respa) } /* ---------------------------------------------------------------------- - free memory for tables used in pair computations + setup force tables for dispersion used in compute routines + ------------------------------------------------------------------------- */ + +void Pair::init_tables_disp(double cut_lj_global) +{ + int masklo,maskhi; + double r, rsq, r2inv, force_coul, force_lj; + double g_ewald_6 = force->kspace->g_ewald_6; + double g2 = g_ewald_6*g_ewald_6, g6 = g2*g2*g2, g8 = g6*g2; + + tabinnerdispsq = tabinner_disp*tabinner_disp; + init_bitmap(tabinner_disp,cut_lj_global,ndisptablebits, + masklo,maskhi,ndispmask,ndispshiftbits); + + int ntable = 1; + for (int i = 0; i < ndisptablebits; i++) ntable *= 2; + + // linear lookup tables of length N = 2^ndisptablebits + // stored value = value at lower edge of bin + // d values = delta from lower edge to upper edge of bin + + if (fdisptable) free_disp_tables(); + + memory->create(rdisptable,ntable,"pair:rdisptable"); + memory->create(fdisptable,ntable,"pair:fdisptable"); + memory->create(edisptable,ntable,"pair:edisptable"); + memory->create(drdisptable,ntable,"pair:drdisptable"); + memory->create(dfdisptable,ntable,"pair:dfdisptable"); + memory->create(dedisptable,ntable,"pair:dedisptable"); + + union_int_float_t rsq_lookup; + union_int_float_t minrsq_lookup; + int itablemin; + minrsq_lookup.i = 0 << ndispshiftbits; + minrsq_lookup.i |= maskhi; + + for (int i = 0; i < ntable; i++) { + rsq_lookup.i = i << ndispshiftbits; + rsq_lookup.i |= masklo; + if (rsq_lookup.f < tabinnerdispsq) { + rsq_lookup.i = i << ndispshiftbits; + rsq_lookup.i |= maskhi; + } + r = sqrtf(rsq_lookup.f); + rsq = rsq_lookup.f; + register double x2 = g2*rsq, a2 = 1.0/x2; + x2 = a2*exp(-x2); + + rdisptable[i] = rsq_lookup.f; + fdisptable[i] = g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; + edisptable[i] = g6*((a2+1.0)*a2+0.5)*x2; + + minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f); + } + + tabinnerdispsq = minrsq_lookup.f; + + int ntablem1 = ntable - 1; + + for (int i = 0; i < ntablem1; i++) { + drdisptable[i] = 1.0/(rdisptable[i+1] - rdisptable[i]); + dfdisptable[i] = fdisptable[i+1] - fdisptable[i]; + dedisptable[i] = edisptable[i+1] - edisptable[i]; + } + + // get the delta values for the last table entries + // tables are connected periodically between 0 and ntablem1 + + drdisptable[ntablem1] = 1.0/(rdisptable[0] - rdisptable[ntablem1]); + dfdisptable[ntablem1] = fdisptable[0] - fdisptable[ntablem1]; + dedisptable[ntablem1] = edisptable[0] - edisptable[ntablem1]; + + // get the correct delta values at itablemax + // smallest r is in bin itablemin + // largest r is in bin itablemax, which is itablemin-1, + // or ntablem1 if itablemin=0 + // deltas at itablemax only needed if corresponding rsq < cut*cut + // if so, compute deltas between rsq and cut*cut + + double f_tmp,c_tmp,e_tmp,p_tmp = 0.0,v_tmp = 0.0; + double cut_lj_globalsq; + itablemin = minrsq_lookup.i & ndispmask; + itablemin >>= ndispshiftbits; + int itablemax = itablemin - 1; + if (itablemin == 0) itablemax = ntablem1; + rsq_lookup.i = itablemax << ndispshiftbits; + rsq_lookup.i |= maskhi; + + if (rsq_lookup.f < (cut_lj_globalsq = cut_lj_global * cut_lj_global)) { + rsq_lookup.f = cut_lj_globalsq; + r = sqrtf(rsq_lookup.f); + + register double x2 = g2*rsq, a2 = 1.0/x2; + x2 = a2*exp(-x2); + f_tmp = g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; + e_tmp = g6*((a2+1.0)*a2+0.5)*x2; + + drdisptable[itablemax] = 1.0/(rsq_lookup.f - rdisptable[itablemax]); + dfdisptable[itablemax] = f_tmp - fdisptable[itablemax]; + dedisptable[itablemax] = e_tmp - edisptable[itablemax]; + } +} + +/* ---------------------------------------------------------------------- + free memory for tables used in Coulombic pair computations ------------------------------------------------------------------------- */ void Pair::free_tables() @@ -474,6 +590,19 @@ void Pair::free_tables() memory->destroy(dptable); } +/* ---------------------------------------------------------------------- + free memory for tables used in pair computations for dispersion + ------------------------------------------------------------------------- */ + +void Pair::free_disp_tables() +{ + memory->destroy(rdisptable); + memory->destroy(drdisptable); + memory->destroy(fdisptable); + memory->destroy(dfdisptable); + memory->destroy(edisptable); + memory->destroy(dedisptable); +} /* ---------------------------------------------------------------------- mixing of pair potential prefactors (epsilon) ------------------------------------------------------------------------- */ @@ -697,7 +826,7 @@ void Pair::ev_tally(int i, int j, int nlocal, int newton_pair, } } } - + /* ---------------------------------------------------------------------- tally eng_vdwl and virial into global and per-atom accumulators can use this version with full neighbor lists diff --git a/src/pair.h b/src/pair.h index c6c22d15d2..0ef7d53392 100644 --- a/src/pair.h +++ b/src/pair.h @@ -65,10 +65,15 @@ class Pair : protected Pointers { int vflag_either,vflag_global,vflag_atom; int ncoultablebits; // size of Coulomb table, accessed by KSpace + int ndisptablebits; // size of dispersion table double tabinnersq; + double tabinnerdispsq; double *rtable,*drtable,*ftable,*dftable,*ctable,*dctable; double *etable,*detable,*ptable,*dptable,*vtable,*dvtable; + double *rdisptable, *drdisptable, *fdisptable, *dfdisptable; + double *edisptable, *dedisptable; int ncoulshiftbits,ncoulmask; + int ndispshiftbits, ndispmask; int nextra; // # of extra quantities pair style calculates double *pvector; // vector of extra pair quantities @@ -138,7 +143,9 @@ class Pair : protected Pointers { virtual double init_one(int, int) {return 0.0;} virtual void init_tables(double, double *); + virtual void init_tables_disp(double); virtual void free_tables(); + virtual void free_disp_tables(); virtual void write_restart(FILE *) {} virtual void read_restart(FILE *) {} @@ -172,6 +179,7 @@ class Pair : protected Pointers { // pair_modify settings int offset_flag,mix_flag; // flags for offset and mixing double tabinner; // inner cutoff for Coulomb table + double tabinner_disp; // inner cutoff for dispersion table // custom data type for accessing Coulomb tables @@ -236,10 +244,6 @@ E: All pair coeffs are not set All pair coefficients must be set in the data file or by the pair_coeff command before running a simulation. -E: Pair style requires a KSpace style - -No kspace style is defined. - E: Pair style does not support pair_write The pair style does not have a single() function, so it can